[英]Why does 'await' change the thread context in WinForms program.cs
The normal behavior of using await to call an asynchronous method is that its context stays the same as shown in the example below: 使用await调用异步方法的正常行为是它的上下文保持不变,如下例所示:
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
private async void Form1_Load(object sender, EventArgs e)
{
//main thread here
await SampleAsync();
//stays as main thread
var g = 10;
}
static async Task SampleAsync()
{
await Task.Delay(1000);
}
}
But when I use this in the Winforms Main console method call, this behavior is no longer true: After calling the await method, the thread change from the main thread to the worker thread. 但是当我在Winforms主控制台方法调用中使用它时,这种行为不再成立:在调用await方法之后,线程从主线程更改为工作线程。 Why is this?
为什么是这样? I would like for it to stay on the Main (UI Thread) after the await call.
我希望它在等待调用后保持在Main(UI线程)上。
[STAThread]
static void Main()
{
Application.EnableVisualStyles();
Application.SetCompatibleTextRenderingDefault(false);
MainAsync().Wait();
}
static async Task MainAsync()
{
Application.Run(new Form1());
//Main Thread here
await Task.Delay(1000);
//Why does it turn in to worker thread here? ConfigureAwait(false) is not used here?!
var g = 5;
//Run other Application.Run() if certain conditions apply; but I need to be in the Main Thread.
}
In case you are wondering what I am trying to achieve, I am trying to catch the errors in the async method, MainAsync, rather than Main so that I can avoid having to disentangle errors from the AggregateException ( https://msdn.microsoft.com/en-us/magazine/JJ991977.aspx ; Figure4). 如果你想知道我想要实现什么,我试图捕获异步方法中的错误,MainAsync,而不是Main,以便我可以避免从AggregateException( https://msdn.microsoft)解开错误。 com / en-us / magazine / JJ991977.aspx ;图4)。 I also want to stay in the UI thread so I can run other Application.Run in the UI thread.
我还想留在UI线程中,这样我就可以在UI线程中运行其他Application.Run。
Because Application.Run
is what "Runs" the continuation on the main thread, once Application.Run
returned SynchronizationContext.Current
was unset for the "UI Thread" therefor the await
had to use the default context which is the ThreadPool. 因为
Application.Run
是“运行”主线程上的延续,所以一旦Application.Run
返回SynchronizationContext.Current
,则为“UI线程”取消设置,因此await
必须使用默认上下文,即ThreadPool。
Because you have no UI at that point I would recommend doing a synchronous wait ( .Wait()
) instead of a await
at that point, that will make sure you are still on the same STA thread for your later Application.Run
calls. 因为此时没有UI,我建议在此时进行同步等待(
.Wait()
)而不是await
,这将确保您仍然在以后的Application.Run
调用的同一个STA线程上。
EDIT : Did not see your mention about disentangling AggregateException, all await is doing with the AggregateException is doing the equivalent of 编辑 :没有看到你提到关于解开AggregateException,所有等待是用AggregateException做的相当于
catch(AggregateException ex)
{
ExceptionDispatchInfo.Capture(ex.InnerException).Throw();
}
Which causes the first exception of the AggregateException to be re-raised without messing up it's stack trace. 这导致重新引发AggregateException的第一个异常,而不会弄乱它的堆栈跟踪。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.