Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/288.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/sorting/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# Task.Run流同步上下文何时与ExecutionContext一起运行?_C#_Asynchronous_Async Await_Synchronizationcontext - Fatal编程技术网

C# Task.Run流同步上下文何时与ExecutionContext一起运行?

C# Task.Run流同步上下文何时与ExecutionContext一起运行?,c#,asynchronous,async-await,synchronizationcontext,C#,Asynchronous,Async Await,Synchronizationcontext,来自以下状态:SynchronizationContext可能与ExecutionContext一起流动: private async void button1_Click(object sender, EventArgs e) { Console.WriteLine("Click context:" + SynchronizationContext.Current); button1.Text = await Task.Run(async delegate {

来自以下状态:
SynchronizationContext
可能与
ExecutionContext
一起流动:

private async void button1_Click(object sender, EventArgs e) {
    Console.WriteLine("Click context:" + SynchronizationContext.Current);
    button1.Text = await Task.Run(async delegate {

        // In my tests this always returns false
        Console.WriteLine("SynchronizationContext was flowed: " + (SynchronizationContext.Current != null));

        string data = await DownloadAsync();
        return Compute(data);
    });
}
下面是我的心智模型告诉我的,这个代码会发生什么。A. 用户单击按钮1,导致UI框架调用按钮1\u单击 在UI线程上。然后,代码启动一个工作项以在 线程池(通过Task.Run)。该工作项开始一些下载工作 并异步等待它完成。后续工作项 然后在线程池上对 下载的结果,并返回结果,导致 正在等待UI线程完成。此时,用户界面 线程处理此按钮单击方法的其余部分,存储 将计算结果输入button1的文本属性

如果SynchronizationContext不作为一部分流动,我的期望是有效的 执行上下文。但是,如果它真的流了,我会非常难过 失望。Task.Run在调用时捕获ExecutionContext,并且 使用它运行传递给它的委托。这意味着用户界面 调用Task.Run时当前的SynchronizationContext 将流入任务,并且在调用时是当前的 下载Async并等待生成的任务。那就意味着 等待将看到当前SynchronizationContext并发布 异步方法的剩余部分作为在 用户界面线程。这意味着我的计算方法很可能是 在UI线程上运行,而不是在线程池上运行,导致 我的应用程序的响应问题

故事现在变得有点混乱:ExecutionContext实际上有两种捕获方法,但是 其中只有一个是公开的。内部的一个(mscorlib的内部) 是从中公开的大多数异步功能所使用的 mscorlib,并且它可以选择性地允许调用方抑制 作为ExecutionContext的一部分捕获SynchronizationContext; 与此相对应,还有一个运行的内部过载 方法,该方法支持忽略存储的SynchronizationContext 在行刑的背景下,实际上是假装一个人没有被抓获 (这也是mscorlib中大多数功能所使用的重载)。 这意味着几乎所有异步操作 核心实现驻留在mscorlib中,不会流动 SynchronizationContext作为ExecutionContext的一部分,但任何 其核心实现位于其他任何位置的异步操作 将同步上下文作为ExecutionContext的一部分流动。我 前面提到异步方法的“构建器”是 负责在异步方法中流动ExecutionContext的类型,以及 这些构建器确实生活在mscorlib中,并且使用内部 重载…因此,SynchronizationContext不会作为 跨等待的ExecutionContext(同样,这与任务的方式是分开的) 等待者支持捕获同步上下文和发布 回到它)。帮助处理ExecutionContext无法处理的情况 流同步上下文,异步方法基础结构尝试 忽略由于流动而设置为当前的SynchronizationContext

然而,我并不清楚什么时候会发生这种情况。当使用public
ExecutionContext.Capture
方法且未使用内部
Task.Run
重载来抑制流动
SynchronizationContext
with
ExecutionContext
时,似乎会发生这种情况,但我不知道何时会发生这种情况

在我对.NET 4.5的测试中,
任务.Run
似乎没有将
SynchronizationContext
ExecutionContext
流动:

private async void button1_Click(object sender, EventArgs e) {
    Console.WriteLine("Click context:" + SynchronizationContext.Current);
    button1.Text = await Task.Run(async delegate {

        // In my tests this always returns false
        Console.WriteLine("SynchronizationContext was flowed: " + (SynchronizationContext.Current != null));

        string data = await DownloadAsync();
        return Compute(data);
    });
}
所以我的问题是,在什么情况下,
Compute()

Task.Run流同步上下文何时与ExecutionContext一起运行

从来没有

那篇文章的要点是(用于)流动
ExecutionContext
的公共API将流动
SynchronizationContext
。但是
Task.Run
(以及“几乎所有核心实现驻留在mscorlib中的异步操作”)永远不会这样做

以“如果”开头的段落是假设性的。他描述了如果
Task.Run
使用公共API流动
ExecutionContext
会发生什么。如果它这样做的话,就会产生问题。这就是为什么它从来没有这样做过