简体   繁体   English

在.NET 4.0中等待替代方案?

[英]Await alternative in .NET 4.0?

What would be the best alternative for the await keyword in .NET 4.0 ? 什么是.NET 4.0中await关键字的最佳替代方案? I have a method which needs to return a value after an asynchronous operation. 我有一个方法,需要在异步操作后返回一个值。 I noticed the wait() method blocks the thread completely thus rendering the asynchronous operation useless. 我注意到wait()方法完全阻塞了线程,从而使异步操作无效。 What are my options to run the async operation while still freeing the UI thread ? 在释放UI线程的同时运行异步操作有哪些选择?

I think your basic options are 我认为你的基本选择是

The easiest way is probably to install the Async CTP. 最简单的方法是安装Async CTP。 As far as I know the license allows comercial usage. 据我所知,许可证允许商业用途。 It patches the compiler and comes with a 150kb dll that you can include into your project. 它会修补编译器并附带一个150kb的dll,您可以将其包含在项目中。

You can use Task and .ContinueWith() . 您可以使用Task.ContinueWith() But that means, that you have to take some effort with exeption handling and flow control. 但这意味着,你必须在exeption处理和流量控制方面付出一些努力。

Tasks are a functional construct. 任务是一个功能构造。 That's why ContinueWith() does not mix well with imperative constructs like for loops or try-catch blocks. 这就是为什么ContinueWith()for循环或try-catch块等命令式结构不能很好地混合的原因。 Therefore async and await got introduced, so that the compiler can help us out. 因此asyncawait得到了介绍,因此编译器可以帮助我们。

If you can't have that support of the compiler (ie you use .Net 4.0), your best bet is to use the TAP together with a functional framework. 如果您不能获得编译器的支持(即您使用.Net 4.0),最好的办法是将TAP与功能框架一起使用。 Reactive Extensions is a very good framework to treat asynchronous methods. Reactive Extensions是一个非常好的框架来处理异步方法。

Just google for "reactive extensions tasks" to get started. 只需谷歌“反应性扩展任务”即可开始使用。

You could implement a behaviour like await with the yield coroutines, i'm using this in non-4.5 code. 您可以使用yield协程实现类似await的行为,我在非4.5代码中使用它。 You need a YieldInstruction class which is retrieved from the method which should run async: 您需要一个YieldInstruction类,该类从应该运行异步的方法中检索:

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

Then you need some implementations of the YieldInstruction ( ae TaskCoroutine which handles a task ) and use it this way ( Pseudo code ): 然后你需要一些YieldInstruction实现(ae TaskCoroutine来处理一个任务)并以这种方式使用它(伪代码):

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

Now you need a scheduler which handles the execution of the instructions. 现在您需要一个处理指令执行的调度程序。

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

When developing WPF or WinForms applications you are also able to avoid any Invoke calls if you are updating the coroutines at the right time. 在开发WPF或WinForms应用程序时,如果要在正确的时间更新协程,则还可以避免任何Invoke调用。 You also might be able to extend the idea to make your life even easier. 您也可以扩展这个想法,让您的生活更轻松。 Sample: 样品:

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
}

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

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