代码之家  ›  专栏  ›  技术社区  ›  Michael D. Irizarry

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

  •  0
  • Michael D. Irizarry  · 技术社区  · 16 年前

    我正在处理这个Silverlight 3.0项目,它完全充满了对Web服务的异步调用。在主页上,它获取一些所需的数据,以便应用程序使用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 回复  |  直到 16 年前
        1
  •  2
  •   Jeremy Likness    16 年前

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

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

    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);
       }
    }
    

    当然,如果您有大量的多线程,那么您将在这些线程上使用联锁,但大多数时候您将从同一线程调用它。然后,您只需执行以下操作:

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

    然后在返回时,只需:

    GlobalState.EndAsync();
    

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

        2
  •  0
  •   Ramon Smits    16 年前
    1. 在Silverlight中创建工作项的单位
    2. 此UOW在完成时引发事件
    3. 将该事件绑定到您的GUI代码
    4. 使用信令或工作单元中的简单计数器来引发“已完成”事件。