【发布时间】:2011-07-01 16:54:03
【问题描述】:
.NET 4.0 的 TPL 包含了很好的 Task 类来封装异步编程模型。我正在开发一个必须是 .NET 2.0 的应用程序,但我想避免重写 Task。有什么建议吗?
【问题讨论】:
标签: c# .net asynchronous task task-parallel-library
.NET 4.0 的 TPL 包含了很好的 Task 类来封装异步编程模型。我正在开发一个必须是 .NET 2.0 的应用程序,但我想避免重写 Task。有什么建议吗?
【问题讨论】:
标签: c# .net asynchronous task task-parallel-library
我知道你说过你不想重写 Task,但你实际上可以使用闭包创建一些相当简单的东西,它的行为有点像 Task 对象。这是我使用的:
public delegate R AsyncTask<R>();
public static AsyncTask<R> BeginTask<R>(AsyncTask<R> function)
{
R retv = default(R);
bool completed = false;
object sync = new object();
IAsyncResult asyncResult = function.BeginInvoke(
iAsyncResult =>
{
lock (sync)
{
completed = true;
retv = function.EndInvoke(iAsyncResult);
Monitor.Pulse(sync);
}
}, null);
return delegate
{
lock (sync)
{
if (!completed)
{
Monitor.Wait(sync);
}
return retv;
}
};
}
它是一个在您传入的委托上调用 BeginInvoke() 的函数,并返回一个函数,该函数在调用时会阻塞并等待传入函数的结果。您必须为不同的方法创建此函数的重载签名,当然。
一种方法,您可以根据自己的需要对其进行调整,并添加其他行为,例如 Continuations 等。关键是使用闭包和匿名委托。应该在 .NET 2.0 中工作。
编辑 - 以下是您将如何使用它:
public static string HelloWorld()
{
return "Hello World!";
}
static void Main(string[] args)
{
var task = BeginTask(HelloWorld); // non-blocking call
string result = task(); // block and wait
}
【讨论】:
您必须使用 System.Threading.Thread 类,您可以为 .net 3.5 获取 Task 类,但不适用于 .net 2。
对不起
【讨论】:
Task 和其他低级抽象(但不是整个 TPL)反向移植到 .NET 3.5 SP1。