WCF异步调用轮询或标记 - 最佳实践

时间:2010-07-29 13:31:51

标签: c# silverlight wcf callback asynchronous

我正在开发这个完全充满对Web服务的异步调用的Silverlight 3.0项目。在主页面上,它会获取一些所需的数据,以便应用程序使用3个异步调用正常工作。现在,应用程序在执行这些调用时不会禁用任何控件,这意味着用户可以在没有所需数据的情况下与其进行交互。我需要禁用整个网格,并且只有在完成所有3个异步调用之后才启用网格。

这样做的最佳做法是什么。

这些是我的电话:

client.GetAllAsync();
client.GetAllCompleted += new EventHandler<GetAllCompletedEventArgs>(client_GetAllCompleted);

client.GetActualAsync();
client.GetActualCompleted += new EventHandler<GetActualCompletedEventArgs>(client_GetActualCompleted);

client.GetSomeAsync();
client.GetSomeCompleted += new EventHandler<GetSomeCompletedEventArgs>(client_GetSomeCompleted);

2 个答案:

答案 0 :(得分:2)

似乎很多工作只是为了排队一些用户交互性。

我通常提供应用程序范围的界面:

public interface IAppGlobalState 
{
   void BeginAsync(); 
   void EndAsync(); 
}

在实施中,我会这样做:

public partial class MainShell : UserControl, IAppGlobalState 
{
   private int _queue; 
   private object _mutex = new Object();

   public void BeginASync()
   {
      Monitor.Enter(_mutex);
      if (_queue++ == 0)
      {
         VisualStateManager.GoToState(this, "BusyState", true);
      }
      Monitor.Exit(_mutex);
   }

   public void EndAsync()
   {
      Monitor.Enter(_mutex);
      if (--_queue == 0)
      {
         VisualStateManager.GoToState(this, "IdleState", true); 
      }
      Monitor.Exit(_mutex);
   }
}

当然,如果你有繁重的多线程,那么你将使用Interlocked,但大多数时候你将从同一个线程调用它。然后,你只需:

GlobalState.BeginAsync();
client.FirstAsyncCall();

GlobalState.BeginAsync();
client.FirstAsyncCall();

然后回来,只是:

GlobalState.EndAsync();

如果你有嵌套调用,没问题,这个方法会解开它们。

答案 1 :(得分:0)

  1. 在silverlight中制作一个工作单元
  2. 这个UOW在完成时引发了一个事件
  3. 将该事件绑定到您的GUI代码
  4. 在您的工作单元中使用信号或简单的计数器来提升“已完成”事件。