我有BeginInvoke
代理人internally invokes multiple asynchronous operations
,我想等待所有内部操作完成before callback for main asynchronous operation executes.
我可以使用async, await or TPL
轻松实现这一目标,但由于我的目标平台为.Net3.5
,因此无法实现。示例代码演示了我的问题 -
class Program
{
static List<string> abc = new List<string>();
static void Main(string[] args)
{
new Action(() =>
{
A();
}).BeginInvoke(MainCallback, null);
}
static void MainCallback(IAsyncResult result)
{
foreach (string str in abc)
{
Console.WriteLine(String.Format("Main Callback {0}",str));
}
}
static void A()
{
for (int i = 0; i < 10; i++)
{
new Action(() =>
{
Thread.Sleep(1000);
}).BeginInvoke(Callback, i);
}
}
static void Callback(IAsyncResult result)
{
abc.Add(result.AsyncState.ToString());
}
}
我希望输出是这样的 -
Main Callback 0
Main Callback 1
Main Callback 2
Main Callback 3
Main Callback 4
Main Callback 5
Main Callback 6
Main Callback 7
Main Callback 8
Main Callback 9
答案 0 :(得分:4)
您需要跟踪已启动的操作数量。
然后,在每个回调中,递减此计数器(以指示其中一个操作已完成)。
当它达到0
时,一切都已完成,因此您可以调用最终的回调。
这就是Task.WhenAll()
的工作方式。
由于这是一个多线程环境,因此必须使用Interlocked.Decrement
(仔细)。
答案 1 :(得分:-1)
您可以通过修改一些代码来实现预期的输出。
修改您的A
方法,如下所示。你已经完成了
static void A()
{
List<IAsyncResult> results = new List<IAsyncResult>();
for (int i = 0; i < 10; i++)
{
results.Add(new Action(() =>
{
Thread.Sleep(1000);
}).BeginInvoke(Callback, i));
}
foreach (var res in results)
{
res.AsyncWaitHandle.WaitOne();
}
}
这有帮助吗?