.NET 4.0中有等待的替代方案吗?

10

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


1
使用await,但要用对了吧。你有代码吗? - lboshuizen
3
在使用.net 4.0时,是否可以使用VS2012和C# 5.0?请参见在.net 4上使用async-await - CodesInChaos
对于同事,不行 :)。 - Dante
为什么不使用continuations? - Dennis
你最终使用了什么? - Felix K.
@FelixK。我使用了任务的ContinueWith()方法。 - Dante
2个回答

4
我认为您的基本选项是: 最简单的方法可能是安装Async CTP。据我所知,许可证允许商业使用。它会修补编译器并附带一个150kb的dll,您可以将其包含到项目中。
您可以使用Task.ContinueWith()。但这意味着您必须在异常处理和流程控制方面付出一些努力。
任务是一种功能构造。这就是为什么ContinueWith()for循环或try-catch块等命令式构造不兼容的原因。因此,引入了asyncawait,以便编译器可以帮助我们。
如果您无法获得编译器的支持(即使用 .Net 4.0),最好使用TAP与函数框架一起使用。Reactive Extensions是一个非常好的框架,用于处理异步方法。
只需搜索“reactive extensions tasks”开始使用。

2

你可以使用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
}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接