我试图编写一个测试某些条件并返回值的函数,但如果条件不满意,它会等待然后再试一次。当然,我可以投入一个Thread.Sleep
,但我认为我应该能够通过任务asynch
/ await
来解决这个问题,但我无法做到非常合适的语法使这项工作。例如:
public async Task<T> Get<T>(TimeSpan waittime)
{
if (someCondition)
{
return SomeFunctionThatReturnsValue<T>();
}
else
{
return await Get<T>(waitime);
}
}
有效,但没有任何延迟(显然),所以我尝试过多种变体:
public async Task<T> Get<T>(TimeSpan waittime)
{
if (someCondition)
{
return SomeFunctionThatReturnsValue<T>();
}
else
{
return await Task.Delay(waittime).ContinueWith(t => Get<T>(waitime));
}
}
但是这给了我编译时错误:
Error 52 Since this is an async method, the return expression must be of type 'T' rather than 'Task<T>'
我可以将最后return
更改为:
return await Task.Delay(waittime).ContinueWith(t => Get<T>(waittime).Result);
它编译,但这似乎也不正确。
答案 0 :(得分:4)
由于您希望您的方法是异步的,当您想要获得Task
的结果时,您应该使用await
,而不是Result
,以便异步执行操作,所以你可以把这个操作写成:
return await await Task.Delay(waittime).ContinueWith(t => Get<T>(waitime));
或者,只要您有两个等待,您就可以使用Unwrap
;它并不是真的好或坏;它的等价物:
return await Task.Delay(waittime).ContinueWith(t => Get<T>(waitime)).Unwrap();
请注意,通过使用Unwrap
,您还可以使该方法不是async
而不是await
,因为Unwrap
已经在完成转换{{1}进入Task<Task<T>>
。
当然,在大多数情况下,您通常不应该在Task<T>
方法中使用ContinueWith
,您应该只使用async
为您的任务添加延续:
await
还值得注意的是,你应该在这里使用await Task.Delay(waittime)
return Get<T>(waitime);
循环,而不是使用递归,特别是因为你有一个while
方法,这意味着构建另一个< / em>每个递归调用的状态机。