只有当所有异步操作完成后,如何才能继续我的应用程序?

时间:2012-02-20 13:04:42

标签: c# windows-phone-7

在我的应用程序中,我曾经创建了一系列异步操作,它们传递了这样的函数:

public void LotsOfAsync()
{
    DoAsync1( ()=> { DoAsync2( ()=> { doAsync3( ()=> { finalAction();}) } ) } );
}

但是,现在我已将许多异步操作移动到单独的类和对象中,但我想要相同的结果。主要是我已将这些异步操作移动到成为集合一部分的类中。

我希望我的新代码看起来像这样:

public void lotsOfAsync()
{
    DoAsync1();
    for each ( MyClass in Async1List)
     { 
          MyClass.DoAsyn2(); 
      }
    if (allAsyncOperationsAreComplete)
    {
        FinalAction();
    }
}

我需要做些什么才能让它发挥作用?感谢。


使用下面关于任务的答案,似乎仍然缺乏某些东西。即使将所有内容都放入BackgroundWorker中,该程序也永远不会继续。

5 个答案:

答案 0 :(得分:4)

您可以使用Task<T>(使用Task Parallel Library for 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();
});

答案 1 :(得分:2)

我不熟悉wp7,但您可以将计数器用作静态字段,并在最终操作中检查它是否等于0.

每个MyClass.DoAsyn2()都应触发一个事件或任何其他代码来表示它已完成。

另一种选择是将所有异步移动到任务并调用Task.WaitAll

http://msdn.microsoft.com/en-us/library/dd270695.aspx

答案 2 :(得分:1)

您是否看过.Net 4中的CountdownEvent?这是一个信令构造,其中一个线程将阻塞,并且只有在其他线程完成后才进行,并在倒计时事件上调用set。在构造中调用Wait的线程继续进行之前,您需要使用所需的信号数来初始化它。 E.g:

 CountdownEvent countdown = new CountdownEvent(3);
只有当其他3个线程调用Wait时,

才会让调用Signal的线程继续运行。

所以你的例子可能看起来像这样:

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重现此内容。

还有一个很好的例子here。希望这有帮助!

答案 3 :(得分:1)

在查看了之前的所有答案之后,我无法解决我的问题。

而我需要做的是在我的类中创建自定义事件,这些事件在成功完成异步任务时触发。

对我来说最有用的网站是: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();
                }
            }
        }

答案 4 :(得分:0)

您是否听说过Javascript中经常使用的延迟模式?

使用简单且非常动态,您应该能够在Windows手机上实现它。

查看本指南 http://twistedmatrix.com/documents/current/core/howto/defer.html

此致 托拜厄斯