所以我有以下代码
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");
}
Run Code Online (Sandbox Code Playgroud)
直到两个MessageBox都显示为主线程是块(我的意思是应用程序本身被冻结).我的代码显然有问题,我无法弄清楚是什么.我以前从未使用async/await.这是我的第一次尝试.
编辑:
实际上我想要做的是DoSomethingAsync异步启动Execution,这样当单击按钮时,MessageBox.Show("Test");即使DoSomethingAsync不完整也会执行.
Tho*_*que 34
我想你误解了异步意味着什么.这并不意味着该方法在另一个线程中运行!!
异步方法同步运行直到第一个await,然后将a返回Task给调用者(除非是async void,然后它不返回任何内容).当正在等待的任务完成时,执行将继续执行await,通常在同一个线程上(如果有的话SynchronizationContext).
在你的情况下,Thread.Sleep它在第一个await之前,所以它在控制返回给调用者之前同步执行.但即使它在之后await,它仍将阻止UI线程,除非您专门配置awaiter不捕获同步上下文(使用ConfigureAwait(false)).
Thread.Sleep是一种阻止方法.如果你想要一个异步等价物,请await Task.Delay(3000)按照Sriram Sakthivel的回答中的建议使用.它将立即返回,并在3秒后恢复,而不会阻止UI线程.
异步与多线程有关,这是一种常见的误解.它可以,但在许多情况下它不是.不会因为方法而隐式生成新线程async; 对于要生成的新线程,必须在某个时刻明确地完成.如果您特别希望该方法在不同的线程上运行,请使用Task.Run.
Sri*_*vel 10
您应该注意,标记的方法async在缺少时将不再表现为异步await.你有关于这个的编译器警告.
警告1此异步方法缺少"等待"操作符并将同步运行.考虑使用'await'运算符等待非阻塞API调用,或'await Task.Run(...)'在后台线程上执行CPU绑定工作.
你应该注意那些警告.
异步进行.当我说异步时,它实际上是异步而不是另一个线程中的同步作业.使用Task.Delay哪个是异步的.使用Task.Run了其中一些是CPU密集型耗时的工作.
private async void button1_Click(object sender, EventArgs e)
{
await DoSomethingAsync();
}
private async Task DoSomethingAsync()
{
await Task.Delay(3000); // simulate job
MessageBox.Show("DoSomethingAsync is done");
await DoSomething2Async();
}
private async Task DoSomething2Async()
{
await Task.Delay(3000); // simulate job
MessageBox.Show("DoSomething2Async is done");
}
Run Code Online (Sandbox Code Playgroud)
你没有异步做任何事情.尝试:
await Task.Run(() => Thread.Sleep(3000))
Run Code Online (Sandbox Code Playgroud)
当你等待一个方法时,你实际上正在做的是提供一个回调,其后面的代码就像它完成后执行的那样(在以前的async版本中,你实际上必须自己设置它).如果你什么都不做,await那么这个方法实际上并不是异步的.
有关详细信息,您可能会比在此处查看更糟糕:
http://msmvps.com/blogs/jon_skeet/archive/2011/05/08/eduasync-part-1-introduction.aspx
编辑后; 试试这个:
public void MyMessageBox()
{
var thread = new Thread(() =>
{
MessageBox.Show(...);
});
thread.Start();
}
Run Code Online (Sandbox Code Playgroud)
虽然,你确定它真的是你想要的消息框吗?我原以为状态栏/进度条更新会更合适.