如何进行一系列异步调用,然后使用第一个线程返回的值
本文关键字:第一个 线程 返回 然后 一系列 何进行 异步 调用 | 更新日期: 2023-09-27 18:32:58
我想进行异步调用,然后处理第一个线程返回的值。我不想使用并行库。我只能使用.Net 2.0。我已经编写了以下程序,应该足以满足我的要求。但是有人可以指出是否有更好的解决方案吗?谢谢。
这是我的代码:
class Program
{
private static Worker _worker2;
private static Worker _worker3;
private static Worker _worker4;
private static Worker _worker1;
delegate void DoWorkDelegate(object param);
private static Worker _firstReturnedWorker = null;
private static object lockObject = new object();
public static void Main()
{
_worker1 = new Worker();
_worker2 = new Worker();
_worker3 = new Worker();
_worker4 = new Worker();
int i = 10;
DoWorkDelegate d1 = new DoWorkDelegate(_worker1.OnDoWork);
d1.BeginInvoke(1, OnThreadReturned, ++i);
DoWorkDelegate d2 = new DoWorkDelegate(_worker2.OnDoWork);
d2.BeginInvoke(2, OnThreadReturned, ++i);
DoWorkDelegate d3 = new DoWorkDelegate(_worker3.OnDoWork);
d3.BeginInvoke(3, OnThreadReturned, ++i);
DoWorkDelegate d4 = new DoWorkDelegate(_worker4.OnDoWork);
d4.BeginInvoke(4, OnThreadReturned, ++i);
Console.ReadKey();
}
private static void OnThreadReturned(IAsyncResult ar)
{
lock (lockObject)
{
if (_firstReturnedWorker == null)
{
var workerIdentifier = (int)ar.AsyncState;
switch (workerIdentifier)
{
case 11:
_firstReturnedWorker = _worker1;
break;
case 12:
_firstReturnedWorker = _worker2;
break;
case 13:
_firstReturnedWorker = _worker3;
break;
case 14:
_firstReturnedWorker = _worker4;
break;
}
}
else
{
return;
}
}
Console.WriteLine("First result received was {0}", _firstReturnedWorker.ReturnedValue);
}
}
public class Worker
{
public string ReturnedValue { get; private set; }
public void OnDoWork(object value)
{
ReturnedValue = Process((int)value);
}
private string Process(int numberToProcess)
{
return string.Format("{0} was processed by {1}", numberToProcess, Thread.CurrentThread.ManagedThreadId);
}
}
您的代码看起来应该可以工作,到目前为止还可以。
您可以通过将 Worker 实例对象作为AsyncState
而不是幻数传递来清理它。那么你也不需要OnThreadReturned
中的switch
。
另一种方法是将所有IAsyncResult.AsyncWaitHandle
放在一个数组中并调用WaitHandle.WaitAny
。不过,这会产生更多的开销,因为WaitHandle
是按需创建的,因此在回调解决方案中不需要。它们是实际的内核对象,因此这可能很重要。