只有在所有异步操作完成后,我才能让我的应用程序继续运行
本文关键字:我的 应用程序 运行 继续 异步操作 | 更新日期: 2023-09-27 18:25:06
在我的应用程序中,我曾经创建异步操作的字符串,这些操作传递了如下函数:
public void LotsOfAsync()
{
DoAsync1( ()=> { DoAsync2( ()=> { doAsync3( ()=> { finalAction();}) } ) } );
}
然而,现在我已经将许多异步操作移到了单独的类和对象中,但我想要相同的结果。主要是我已经将这些异步操作转移到类中,这些类成为集合的一部分。
我希望我的新代码看起来像这样:
public void lotsOfAsync()
{
DoAsync1();
for each ( MyClass in Async1List)
{
MyClass.DoAsyn2();
}
if (allAsyncOperationsAreComplete)
{
FinalAction();
}
}
我需要做什么才能让它发挥作用?谢谢
使用下面关于任务的答案,似乎仍然缺少一些东西。即使把所有东西都投入到BackgroundWorker中,该程序也永远不会继续。
您可以使用Task<T>
(使用Silverlight的任务并行库)-可能是这样的:
List<Task> tasks = new List<Task>();
Task.Factory.StartNew(() => DoAsync1()).ContinueWith(_ =>
{
foreach (MyClass myClass in Async1List)
{
tasks.Add(Task.Factory.StartNew(() => myClass.DoSomething()));
}
Task.WaitAll(tasks.ToArray());
FinalAction();
});
我不熟悉wp7,但您可以使用counter作为静态字段,并在最终操作中检查它是否等于0。
每个MyClass.DoAsyn2()都应该触发一个事件,或者任何其他代码来表示它已经完成。
另一种选择是将所有异步转移到任务并调用task.WaitAll
http://msdn.microsoft.com/en-us/library/dd270695.aspx
您看过.Net 4中的CountdownEvent吗?这是一个信号结构,其中一个线程将阻塞,并且只有在其他线程完成并在倒计时事件上调用set后才继续。在构造上调用Wait
的线程继续进行之前,您可以使用所需的信号数量对其进行初始化。例如:
CountdownEvent countdown = new CountdownEvent(3);
将只允许调用CCD_ 3的线程在3个其他线程调用了CCD_。
所以你的例子可能看起来像这样:
public void lotsOfAsync()
{
Int32 numberOfAsyncProcesses = Async1List.Length + 1;
CountdownEvent countdown = new CountdownEvent (numberOfAsyncProcesses);
DoAsync1(countdown); // call countdown.signal() in the async method once complete.
for each ( MyClass in Async1List)
{
// call countdown.signal() in the async method once complete.
MyClass.DoAsyn2(countdown);
}
if(countDown.Wait(TimeSpan.FromSeconds(3))
{
FinalAction();
}
}
我还添加了一个超时,如果未能从所有处理线程获得响应,调用线程将在3秒后解除锁定。在这种情况下,将不会执行最终操作。
如果您的目标不是.Net 4,则可以使用Monitor/Pulse来重现此情况。
这里也有一个很好的例子。希望这能有所帮助!
看完之前的所有答案后,我无法解决我的问题。
相反,我需要做的是在类中创建自定义事件,它在异步任务成功完成时触发。
事实证明,对我来说最有用的网站是:http://www.marten-online.com/csharp/simple-custom-event-handling.html
我的最终代码看起来像这样:
public void lotsOfAsync()
{
DoAsync1();
for each ( MyClass in Async1List)
{
MyClass.PropertyChange += new MyClass.PropertyChangeHandler(Async2Complete);
MyClass.DoAsyn2();
}
}
public void Async2Complete(object sender, PropertyChangeEventArgs data)
{
if (data.PropertyName == "AsyncComplete")
{
totalAsyncCompleted++;
if (totalAsyncCompleted >= Async1List.Count)
{
FinalAction();
}
}
}
您听说过Javascript中经常使用的Deferred模式吗?
它操作简单,非常动态,您应该能够在Windows手机上实现它。
看看这本指南http://twistedmatrix.com/documents/current/core/howto/defer.html
问候Tobias