繁体   English   中英

在异步方法中使用await时如何访问Task对象?

[英]How can I access the Task object when using await in an async method?

在下面的代码中,按button1进行冗长的计算并将结果显示在窗口标题栏中。 它可以工作,但是我可以访问任务的Status以检查任务是否成功运行( TaskStatus.RanToCompletion )吗?

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;
}

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

例如:

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

如果您真的想要,您可以

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

但这是没有意义的,因为如果您在await之后排队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后进行测试会告诉您一些您已经知道的东西。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM