只有在所有异步操作完成后,我才能让我的应用程序继续运行

本文关键字:我的 应用程序 运行 继续 异步操作 | 更新日期: 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