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

C# 只有当所有异步操作都完成时,我如何才能让我的应用程序继续?,c#,windows-phone-7,C#,Windows Phone 7,在我的应用程序中,我常常创建一系列异步操作,这些操作传入如下函数: public void LotsOfAsync() { DoAsync1( ()=> { DoAsync2( ()=> { doAsync3( ()=> { finalAction();}) } ) } ); } public void lotsOfAsync() { DoAsync1(); for each ( MyClass in Async1List) {

在我的应用程序中,我常常创建一系列异步操作,这些操作传入如下函数:

public void LotsOfAsync()
{
    DoAsync1( ()=> { DoAsync2( ()=> { doAsync3( ()=> { finalAction();}) } ) } );
}
public void lotsOfAsync()
{
    DoAsync1();
    for each ( MyClass in Async1List)
     { 
          MyClass.DoAsyn2(); 
      }
    if (allAsyncOperationsAreComplete)
    {
        FinalAction();
    }
}
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();      
    }
}
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();
                }
            }
        }
但是,现在我已经将许多异步操作移到了单独的类和对象中,但我希望得到相同的结果。我主要是将这些异步操作移动到类中,这些类成为集合的一部分

我希望我的新代码如下所示:

public void LotsOfAsync()
{
    DoAsync1( ()=> { DoAsync2( ()=> { doAsync3( ()=> { finalAction();}) } ) } );
}
public void lotsOfAsync()
{
    DoAsync1();
    for each ( MyClass in Async1List)
     { 
          MyClass.DoAsyn2(); 
      }
    if (allAsyncOperationsAreComplete)
    {
        FinalAction();
    }
}
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();      
    }
}
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();
                }
            }
        }
我需要做些什么才能让这一切顺利进行?谢谢



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

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

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

另一个选项是将所有异步移动到task并调用task.WaitAll


您听说过Javascript中经常使用的延迟模式吗

它使用起来很简单,而且非常动态,您应该能够在Windows phone上实现它

看看这本指南

问候 Tobias

您可以使用
任务
(使用)-类似于以下内容:

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();
});
List tasks=newlist();
Task.Factory.StartNew(()=>DoAsync1()).ContinueWith(\u=>
{
foreach(异步列表中的MyClass MyClass)
{
tasks.Add(Task.Factory.StartNew(()=>myClass.DoSomething());
}
Task.WaitAll(tasks.ToArray());
FinalAction();
});

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

 CountdownEvent countdown = new CountdownEvent(3);
只有在其他3个线程调用了
信号
后,才会让调用
的线程等待
继续

因此,您的示例可能如下所示:

public void LotsOfAsync()
{
    DoAsync1( ()=> { DoAsync2( ()=> { doAsync3( ()=> { finalAction();}) } ) } );
}
public void lotsOfAsync()
{
    DoAsync1();
    for each ( MyClass in Async1List)
     { 
          MyClass.DoAsyn2(); 
      }
    if (allAsyncOperationsAreComplete)
    {
        FinalAction();
    }
}
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();      
    }
}
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();
                }
            }
        }
我还添加了一个超时,如果无法从所有处理线程获得响应,调用线程将在3秒钟后解除阻塞。在这种情况下,将不执行最终操作

如果您不是针对.NET4,可以使用Monitor/Pulse来复制此功能


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

看了前面所有的答案后,我无法解决我的问题

相反,我需要做的是在我的类中创建自定义事件,它在异步任务成功完成时触发

对我来说,实现这一目标最有用的网站是:

我的最终代码如下所示:

public void LotsOfAsync()
{
    DoAsync1( ()=> { DoAsync2( ()=> { doAsync3( ()=> { finalAction();}) } ) } );
}
public void lotsOfAsync()
{
    DoAsync1();
    for each ( MyClass in Async1List)
     { 
          MyClass.DoAsyn2(); 
      }
    if (allAsyncOperationsAreComplete)
    {
        FinalAction();
    }
}
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();      
    }
}
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();
                }
            }
        }

好吧,这比我的技巧还要好,它几乎已经实现并可以使用了。这是正确的答案,但它没有帮助我理解如何触发这些事件。如果您解释了这些部分,我可以接受。谢谢,myClass.DoSomething()是否必须返回任何特殊的内容才能工作?不,事实上,在上面的示例中,它返回的任何内容都会被忽略Windows Phone 7上似乎也不存在任务:(@Bob:我在上面链接了一个nuget软件包,该软件包应该可以纠正以下问题:对于阅读此答案的未来用户,Visual Studio的Windows Phone版本不支持传统的安装nuget的方式,但您可以手动安装它。但是,您无法卸载它。您知道Windows Phone sdk是否支持.Net 4吗?我尝试使用Wait和async b之前,但出现了无法识别关键字的错误。不,很遗憾,您可以自己实现相同的功能-请参见:注意:我将使用Interlocked.Increment(ref totalAsyncCompleted),因为增量不是原子操作(读取后跟随modify,然后跟随write指令,这些操作可能会被抢占).