我有一个WinForms应用程序,我有一些代码需要在UI线程上运行.但是,在await不同的线程上运行后的代码.
protected override async void OnHandleCreated(EventArgs e)
{
base.OnHandleCreated(e);
// This runs on the UI thread.
mainContainer.Controls.Clear();
var result = await DoSomethingAsync();
// This also needs to run on the UI thread, but it does not.
// Instead it throws an exception:
// "Cross-thread operation not valid: Control 'mainContainer' accessed from a thread other than the thread it was created on"
mainContainer.Controls.Add(new Control());
}
Run Code Online (Sandbox Code Playgroud)
我也试过明确添加ConfigureAwait(true),但没有区别.我的理解是,如果我省略ConfigureAwait(false),那么继续应该在原始线程上运行.在某些情况下这是不正确的吗?
我还注意到,如果我在await之前向集合添加一个控件,那么延续会在正确的线程上神奇地运行.
protected override async void OnHandleCreated(EventArgs e)
{
base.OnHandleCreated(e); …Run Code Online (Sandbox Code Playgroud) 我正在尝试更多地了解它SynchronizationContext,所以我制作了这个简单的控制台应用程序:
private static void Main()
{
var sc = new SynchronizationContext();
SynchronizationContext.SetSynchronizationContext(sc);
DoSomething().Wait();
}
private static async Task DoSomething()
{
Console.WriteLine(SynchronizationContext.Current != null); // true
await Task.Delay(3000);
Console.WriteLine(SynchronizationContext.Current != null); // false! why ?
}
Run Code Online (Sandbox Code Playgroud)
如果我理解正确,await操作员会捕获当前的信息SynchronizationContext然后将其余的异步方法发布到它.
但是,在我的应用程序中,之后SynchronizationContext.Current为null await.这是为什么 ?
编辑:
即使我自己使用SynchronizationContext它也不会被捕获,尽管它的Post功能被调用.这是我的SC:
public class MySC : SynchronizationContext
{
public override void Post(SendOrPostCallback d, object state)
{
base.Post(d, state);
Console.WriteLine("Posted");
}
}
Run Code Online (Sandbox Code Playgroud)
这就是我使用它的方式:
var sc = new MySC();
SynchronizationContext.SetSynchronizationContext(sc); …Run Code Online (Sandbox Code Playgroud)