2017-01-13 18 views
0

在以下代码中,按下button1会执行冗长的计算并在窗口标题栏中显示结果。它可以工作,但是我可以访问任务的Status以检查任务是否成功运行(TaskStatus.RanToCompletion)?如何在异步方法中使用await时访问Task对象?

async private void button1_Click(object sender, EventArgs e) 
{ 
    Text = "Working"; 
    int val = await LongTask(); 
    Text = "Done: " + val; 
} 

async Task<int> LongTask() 
{ 
    return await Task.Run(() => LongFunction()); 
} 

int LongFunction() 
{ 
    Thread.Sleep(5000); 
    return 1; 
} 

回答

3

您可以通过使用属性Task上的属性来检查状态。但是关于async \ await的其中一个好处就是你不需要这样做。当你await,从Task.Run(...)内部委托抛出的任何异常冒泡,你可以捕获它们,就好像它是同步代码。

例如:

Text = "Working"; 
try { 
    int val = await LongTask(); 
    Text = "Done: " + val; 
} 
catch (Exception ex) 
{ 
    // Something went wrong 
} 
1

如果你真的想你可以

var task = SomeMethodAsync(); 
await task; 
var status = task.Status; 

但是,这是毫无意义的,因为如果你在await然后task后线已完成,所以你只要知道这就是答案。

你可以捕捉异常,然后看看情况,从断层区分消除,但可以告诉大家,从异常了,所以再次它是没有意义的。

相反有时候会有用。假设我们有:

public async Task XAsync() 
{ 
    await YAsync(); 
    await ZAsync(); 
} 

现在,让我们说,YAsync具有机会同步返回的。然后,我们可以这样做:

public Task XAsync() 
{ 
    Task task = YAsync(); 
    if (task.Status == TaskStatus.RanToCompletion) 
    return ZAsync(); 
    // Do the awaiting 
    return XAsync(task); 
} 

private async Task XAsync(Task task) 
{ 
    await task; 
    await ZAsync(); 
} 

避免这样的额外的配置和状态机的建立仅仅是值得的频频命中方法,并再次只值得的,如果第一个任务重复的几率同步是很高。如果出现问题,它也会导致稍微混淆的痕迹,但它可能会产生重大影响。

所以测试await之前的状态有这种用法。在await之后测试告诉你一些你已经知道的东西。

相关问题