【问题标题】:Await alternative in .NET 4.0?等待 .NET 4.0 中的替代方案?
【发布时间】:2012-11-02 21:26:10
【问题描述】:

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

【问题讨论】:

  • 使用等待,但我猜是正确的方式。你有一些代码吗?
  • 在面向 .net 4.0 的同时使用 VS2012 和 C# 5.0 是否可以接受?见Using async-await on .net 4
  • @CodesInChaos 对于同事,没有:)。
  • 为什么不使用延续?
  • 你最后用了什么?

标签: c# .net task-parallel-library c#-5.0


【解决方案1】:

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

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
}

【讨论】:

    【解决方案2】:

    我认为你的基本选择是

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

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

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

    如果您无法获得编译器的这种支持(即您使用 .Net 4.0),那么最好的办法是将TAP 与功能框架一起使用。 Reactive Extensions 是一个非常好的处理异步方法的框架。

    只需在 Google 上搜索“响应式扩展任务”即可开始使用。

    【讨论】:

      猜你喜欢
      • 2014-04-07
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-01-04
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-04-16
      相关资源
      最近更新 更多