2012-09-26 29 views
3

我有这样的方法:异步任务被冻结UI

private async Task DoSomething() 
{ 
    // long running work here. 
} 

当我这样调用它阻止方法的UI:

Task t = DoSomething(); 

我必须做的这些之一使它非阻塞:

Task t = new Task(() => DoSomething()); 
t.Start(); 

// Or 

Task t = Task.Factory.StartNew(() => DoSomething()); 

那么什么是异步的点/等待时,你可以使用任务,因为他们在框架4和使用Task.Wait()代替await

编辑: 我理解你的答案 - 但没有真正解决我的最后一段。任何人都可以给我一个基于任务的多线程示例,其中异步/等待提高了程序的可读性和/或流程?

+2

“异步”的目的不是多线程。它用于异步编程。您可以*使用'Task.Run'执行多线程,但'async'也可以与其他异步操作(如I/O)一起使用。基于任务的异步模式非常强大,因为它可以以同样的方式处理任何异步操作(无论CPU限制,I/O限制还是其他)。 –

回答

2

async方法开始它们的同步执行。 async对编写异步操作很有用,但它不会让代码在另一个线程上运行,除非您告诉它。

您可以使用Task.Run调度CPU绑定工作提高到一个线程池线程。

见我async/await intro postasync FAQ以获取更多信息。

4

你如何使用await?这不会阻止用户界面:

private async Task DoSomething() 
    { 
     await Task.Delay(5000); 
    } 

    private async void button1_Click(object sender, EventArgs e) 
    { 
     await DoSomething(); 
     MessageBox.Show("Finished"); 
    } 

请注意,我没有写任何详细的回调内容。这就是async/await

+1

这不会阻止UI,因为Task.Delay使用在ThreadPool上运行的System.Threading.Timer。尝试使用Thread.Sleep(5000),你会看到UI阻塞。 –

+0

顺便说一句,这个想法,通过使用异步你不需要创建线程似乎是我的完整BS。等待事实只能应用于返回任务或任务的方法,这显然表明某些时候某人将不得不创建一个新的任务! –

+0

@BrunoSantos正确,为你+1,因为提到'System.Threading.Timer' – NPE

0

没有实际的代码,这是很难告诉你这是怎么回事,但你可以开始你的DoSomething“等待Task.Yield();”强制它立即返回,以防在第一次等待之前运行的是什么导致了你的用户界面问题。