使扩展方法异步

时间:2010-05-09 07:16:25

标签: c# .net winforms asynchronous

有什么方法可以使扩展方法异步吗?

我现在已经看了一会儿,但还没有发现任何相关内容。会一直看着......

4 个答案:

答案 0 :(得分:13)

扩展方法只是一个普通的静态方法,用语法糖来调用它。

因此,弄清楚如何使普通方法异步(例如,在.NET 4中启动一个Task)并从那里开始。

答案 1 :(得分:7)

要使任何方法异步,请向方法发送回调,并让方法旋转新线程。

我在.net 3.5中掀起了一个简短的样本(也许Jon会向我们展示一个4.0样本):

 public static void Extension<T>(this T self, AsyncCallback callback )
    {
        var state = new State { callback = callback };
        System.Threading.ThreadPool.QueueUserWorkItem(ExtensionCore, callback);
    }

    private static void ExtensionCore(object state)
    {
        // do stuff with OtherStuff
        var complete = new Complete();
        ((State)state).callback(complete);
    }

    private class State
    {
        public AsyncCallback callback { get; set; }
        public object OtherStuff { get; set; }
    }

    public class Complete : IAsyncResult 
    {  
        public object AsyncState
        {
            get { throw new NotImplementedException(); }
        }

        public System.Threading.WaitHandle AsyncWaitHandle
        {
            get { throw new NotImplementedException(); }
        }

        public bool CompletedSynchronously
        {
            get { throw new NotImplementedException(); }
        }

        public bool IsCompleted
        {
            get { throw new NotImplementedException(); }
        }
    }
}

答案 2 :(得分:4)

我认为他们正试图解决这个问题。无论如何,这很容易解决。这是你如何做到的:

假设您尝试在扩展中使用的异步方法如下所示:

public static async Task DoAsynchronousWork(this string doWorkTo)
{
    await AnotherAsyncFunctionAsync(doWorkTo);
    await DoSomeOtherWorkAsync(doWorkTo);
    await DoMoreWorkAsync(doWorkTo);
}

VS不会对此有所了解,它会编译得很好。但是,如果您尝试调用"MyString".DoAsynchronousWork(),它将抛出一个错误,说它缺少一个字符串参数。所以它并没有完全忽略它是一个扩展的事实,但它仍然需要“this”参数!

幸运的是,很容易解决这个问题。只需将DoAsynchronousWork替换为:

public static Task DoAsynchronousWork(this string doWorkTo)
{
    return new Task(async () => {
        await AnotherAsyncFunctionAsync(doWorkTo);
        await DoSomeOtherWorkAsync(doWorkTo);
        await DoMoreWorkAsync(doWorkTo);
    });
}

我希望他们在发布.NET 4.5之前得到修复,但如果没有,那么至少它很容易解决。 (我发现lambda可能是偶然的异步,但现在它变得非常方便!)

答案 3 :(得分:2)

在切线相关的注释中,Reactive Extensions for .NET提供了有助于异步编程的扩展方法。 .NET 4还有Task Parallel Library(Jon提到),可以帮助并行化集合上的常见操作,并且通常可以极大地简化异常的传播(甚至可以跨多个任务聚合异常),必须在多个并行任务之间进行协调结合他们的结果,支持取消和其他复杂的行为。