等待关键字阻止主线程 [英] await keyword blocks main thread

查看:37
本文介绍了等待关键字阻止主线程的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

所以我有以下代码

private async void button1_Click(object sender, EventArgs e)
{
    await DoSomethingAsync();

    MessageBox.Show("Test");
}

private async Task DoSomethingAsync()
{
    for (int i = 0; i < 1000000000; i++)
    {
        int a = 5;
    }; // simulate job

    MessageBox.Show("DoSomethingAsync is done");

    await DoSomething2Async();
}

private async Task DoSomething2Async()
{
    for (int i = 0; i < 1000000000; i++)
    {
        int a = 5;
    } // simulate job

    MessageBox.Show("DoSomething2Async is done");
}

在显示两个MessageBox之前,主线程处于阻塞状态(我的意思是应用程序本身已冻结).我的代码显然有问题,我不知道是什么.我以前从未使用过async/await.这是我的第一次尝试.

Until both MessageBoxes are shown the main thread is block (I mean the application itself is frozen). There is obviously something wrong with my code and I can't figure out what. I've never used async/await before. this is my first attempt.

实际上,我要做的是异步启动DoSomethingAsync的执行,这样,即使DoSomethingAsync不完整,单击按钮MessageBox.Show("Test");也会执行.

Actually what i want to do is to start Execution of DoSomethingAsync asynchronously so that when button is clicked the MessageBox.Show("Test"); would execute even though the DoSomethingAsync is incomplete.

推荐答案

我认为您误解了异步的含义. 这并不意味着该方法在另一个线程中运行!

I think you misunderstand what async means. It doesn't mean that the method runs in another thread!!

异步方法同步运行,直到第一个await,然后将Task返回给调用者(除非它是async void,然后它什么也不返回).等待的任务完成后,通常在同一线程(如果具有SynchronizationContext)上的await之后恢复执行.

An async method runs synchonously until the first await, then returns a Task to the caller (unless it's async void, then it returns nothing). When the task that is being awaited completes, execution resumes after the await, usually on the same thread (if it has a SynchronizationContext).

在您的情况下,Thread.Sleep在第一次等待之前,因此它是同步执行的,然后将控制权返回给调用者.但是,即使它在await之后,它仍然会阻塞UI线程,除非您特别配置了等待者不捕获同步上下文(使用ConfigureAwait(false)).

In your case, the Thread.Sleep is before the first await, so it's executed synchronously, before control is returned to the caller. But even if it was after the await, it would still block the UI thread, unless you specifically configured the the awaiter not to capture the synchronization context (using ConfigureAwait(false)).

Thread.Sleep是一种阻止方法.如果您想要异步等效项,请按照Sriram Sakthivel的答案中的建议使用await Task.Delay(3000).它会立即返回,并在3秒后恢复,而不会阻塞UI线程.

Thread.Sleep is a blocking method. If you want an async equivalent, use await Task.Delay(3000), as suggested in Sriram Sakthivel's answer. It will return immediately, and resume after 3 seconds, without blocking the UI thread.

一个常见的误解是异步与多线程有关.可以,但是在很多情况下不是.不会仅仅因为方法async而隐式地产生一个新线程.为了产生新线程,必须在某个时候显式地完成它.如果您特别希望该方法在其他线程上运行,请使用Task.Run.

It's a common misconception that async is related to multithreading. It can be, but in many cases it's not. A new thread is not implicitly spawned just because the method is async; for a new thread to spawn, it has to be done explicitly at some point. If you specifically want the method to run on a different thread, use Task.Run.

这篇关于等待关键字阻止主线程的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆