等待中的替代方案.NET 4.0



中的await关键字的最佳替代方案是什么。NET 4.0?我有一个方法,它需要在异步操作后返回一个值。我注意到wait()方法完全阻塞了线程,从而使异步操作变得无用。我有哪些选项可以在释放UI线程的同时运行异步操作?

我认为你的基本选择是

  • 使用Task.ContinueWith()
  • 使用异步CTP和async/await
  • 使用反应式扩展

最简单的方法可能是安装异步CTP。据我所知,许可证允许商业用途。它修补了编译器,并附带了一个150kb的dll,您可以将其包含在项目中。

您可以使用Task.ContinueWith()。但这意味着,您必须在exeption处理和流控制方面付出一些努力。

任务是一个功能结构。这就是为什么ContinueWith()不能很好地与命令式结构(如for循环或try-catch块)混合的原因。因此,引入了asyncawait,以便编译器能够帮助我们。

如果您没有编译器的支持(即使用.Net 4.0),那么最好将TAP与功能框架一起使用。反应式扩展是处理异步方法的一个非常好的框架。

只需在谷歌上搜索"反应式扩展任务"即可开始。

您可以用yield协程实现类似await的行为,我在非4.5代码中使用它。您需要一个YieldInstruction类,该类从应该运行async:的方法中检索

public abstract class YieldInstruction
{
public abstract Boolean IsFinished();
}

然后您需要YieldInstruction的一些实现(例如,处理任务的TaskCoroutine),并以这种方式使用它(伪代码):

public IEnumerator<YieldInstruction> DoAsync()
{
HttpClient client = ....;
String result;
yield return new TaskCoroutine(() => { result = client.DownloadAsync(); });
// Process result here
}

现在您需要一个调度程序来处理指令的执行。

for (Coroutine item in coroutines)  
{  
if (item.CurrentInstruction.IsFinished())  
{
// Move to the next instruction and check if coroutine has been finished 
if (item.MoveNext()) Remove(item);
}
}

在开发WPF或WinForms应用程序时,如果您在正确的时间更新协程,您还可以避免任何Invoke调用。你也可以扩展这个想法,让你的生活更轻松。样品:

public IEnumerator<YieldInstruction> DoAsync()
{
HttpClient client = ....;
client.DownloadAsync(..);
String result;
while (client.IsDownloading)
{
// Update the progress bar
progressBar.Value = client.Progress;
// Wait one update
yield return YieldInstruction.WaitOneUpdate;
}
// Process result here
}

相关内容

最新更新