有什么方法可以使扩展方法异步吗?
我现在已经看了一会儿,但还没有发现任何相关内容。会一直看着......
答案 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提到),可以帮助并行化集合上的常见操作,并且通常可以极大地简化异常的传播(甚至可以跨多个任务聚合异常),必须在多个并行任务之间进行协调结合他们的结果,支持取消和其他复杂的行为。