调用异步方法连续 [英] Calling an asynchronous method serially

查看:165
本文介绍了调用异步方法连续的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有以下(简体)异步方法:

I have the following (simplified) asynchronous method:

void Transform<X,Y>(X x, Action<Y> resultCallback) {...}

和我想要做的是改变两个X的列表为伊苏的列表。

and what I want to do is transform a list of Xs into a list of Ys.

的问题是,即使变换方法是异步的,它必须被连续地调用(即我不得不等待回调与下一个值之前调用它)。

The problem is that even though the Transform method is asynchronous, it has to be called serially (i.e. I have to wait for the callback before calling it with the next value).

有没有什么办法能够完美地做到这一点? (我在.NET 4.0中)

Is there any way to do this elegantly? (I'm on .Net 4.0)

我猜可能有某种方法可以继续通过做...

I'm guessing there might be some way to do it with continuation passing...

更新我忘了指定我不想阻塞调用(GUI)线程。

UPDATE I forgot to specify that I don't want to block the calling (GUI) thread.

推荐答案

如果您在辅助类包装,你可以做帮手同步你的价值观:

If you wrap this in a helper class, you could make the helper "synchronize" your values:

public class AsyncWrapper<X,Y>
{
    ManualResetEvent mre;
    private Y result; 

    public Y Transform(X x, YourClass yourClass)
    {
        mre = new ManualResetEvent(false);
        result = default(Y);

        yourClass.Transform<X,Y>(x, this.OnComplete);
        mre.WaitOne();
        return result;
    }

    void OnComplete(Y y)
    {
        result = y;
        mre.Set();
    }        
}

然后,您可以使用此类似:

You could then use this like:

// instance your class with the Transform operation
YourClass yourClass = new YourClass();

AsyncWrapper<X,Y> wrapper = new AsyncWrapper<X,Y>();

foreach(X x in theXCollection)
{
     Y result = wrapper.Transform(x, yourClass);

     // Do something with result
}


编辑:


既然你说你要做到这一点,以确保一切在后台线程上运行,你可以用我的code以上,并做到:

Since you say you're trying to do this to keep everything running on a background thread, you can use my code above, and do:

// Start "throbber"
Task.Factory.StartNew () =>
{
    // instance your class with the Transform operation
    YourClass yourClass = new YourClass();

    AsyncWrapper<X,Y> wrapper = new AsyncWrapper<X,Y>();

    foreach(X x in theXCollection)
    {
         Y result = wrapper.Transform(x, yourClass);

         // Do something with result
    }
}).ContinueWith( t =>
{
    // Stop Throbber
}, TaskScheduler.FromCurrentSynchronizationContext());

一旦完成这将启动整个(现在同步)进程在后台线程,并禁用活动指示器(从评论)在UI线程上。

This will start the entire (now synchronous) process on a background thread, and disable your "throbber" (from comment) on the UI thread once it completes.

如果你控制了这一切code,你可以让你从一开始转换过程同步,只是将其移动到后台线程如上,避免了需要包装。

If you control all of this code, you can make your Transform process synchronous from the start, and just move it into a background thread as above, avoiding the need for the wrapper.

这篇关于调用异步方法连续的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆