c# - Task.Yield() 之后 SynchronizationContext 丢失

标签 c# async-await synchronizationcontext

我在线程之间传递文化时遇到了问题。我已经设法使用同步上下文让它在某种程度上工作,但在我的代码的一部分中我使用了 Task.Yield()。在这段代码之后,我的上下文丢失,这意味着此后的所有后续等待/产生都不会使用我的自定义 SynchronizationContext。

我将其归结为一个非常简单的测试,我可以看到在我们的 Task.Yield 之后,我们的 SynchronizationContext 丢失了。

同步上下文类:

public class TestSynchronizationContext : SynchronizationContext
{
}

单元测试:

[Test]
public async Task TestHere()
{
    TestSynchronizationContext context = new TestSynchronizationContext();
    SynchronizationContext.SetSynchronizationContext(context);
    var something1 = SynchronizationContext.Current;
    await Task.Yield();
    var something = SynchronizationContext.Current;
}

编辑:如果我使用新任务,如果我可以传入正确的任务调度程序,则上下文将被保留(尽管......它是调度程序,而不是同步上下文)。比如下面这样:

[Test]
public async Task TestHere()
{
    TestSynchronizationContext context = new TestSynchronizationContext();
    SynchronizationContext.SetSynchronizationContext(context);
    CultureInfo taskCulture = null;
        Task.Factory.StartNew(
            () => { taskContext = SynchronizationContext.Current; },
            CancellationToken.None,
            TaskCreationOptions.None,
            TaskScheduler.FromCurrentSynchronizationContext()
            ).Wait();
    Assert.AreEqual(context.GetType(), taskContext.GetType());
}

最佳答案

您的SychronizationContext 必须将自身设置为Current。如果您的 SynchronizationContext 用于专用线程,则只需在主循环中设置一次 current 即可;如果它使用线程池线程来执行(如示例代码中所示),则每当借用其中一个线程时都应该设置它(当然,并在将线程返回到线程池之前清除它)。

关于c# - Task.Yield() 之后 SynchronizationContext 丢失,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/31507127/

相关文章:

c# - 从 DataTemplate 上的按钮获取 ListBox 行对象

c# - TCPClient 异步/等待 C#

c# - 创建 SynchronizationContext 时的异常做法?

c# - 在 Windows 服务中使用 ConfigureAwait(false)?

c# - Visual Studio 2015 100% 的 CPU 使用率与 Node

c# - 设置整个组对目录的访问权限

c# - 如何创建异步 web-api Controller 操作

c# - 任务在 C# 中返回一个 StreamReader

c# - SynchronizationContext 和 InvokeRequired

c# - 尝试在字符串中查找单个字符的更快方法是什么?