【问题标题】:How do I detect waiting asynchronous wcf calls?如何检测等待异步 wcf 调用?
【发布时间】:2009-02-20 05:50:56
【问题描述】:

我从 silverlight 应用程序调用 WCF 服务。 我正在异步执行此操作,并且在进行异步后我不会阻止执行。调用(这意味着,我没有使用等待加入机制 frm this page)。我不希望流程被阻塞。

但是,我想检测到 WCF 调用已进入等待状态,以便我可以在 UI 上显示一个忙碌的图标 - 一种指示 UI 后面正在发生的事情的视觉通信。

我可以更改我的代码,以便我可以开始为忙碌图标设置动画,并在异步调用完成时停止该动画。

但是,这是大量的样板代码,并且在整个客户端代码中进行的调用越来越多,这只会变得更加混乱。

那么,是否有任何由 wcf 服务客户端参考代码公开的方法或属性,可用于在任何异步 wcf 服务调用进入等待状态时触发事件,同样,当所有异步 wcf 服务调用时触发事件服务调用完成了吗?

【问题讨论】:

  • 我在自动生成的 wcf 客户端引用上使用单例包装器,因此我总是使用 wcf 客户端的同一个实例。我的 app.xaml.cs 文件中有一个静态属性,它在整个应用程序中公开这个单例。

标签: wcf silverlight user-interface asynchronous silverlight-2.0


【解决方案1】:

生成的客户端引用类上没有可用于标识对 Silverlight WCF 服务方法的异步调用当前正在进行的属性或事件。不过,您可以使用简单的布尔变量自己记录这一点,或者使用您提到的在这种情况下要避免的阻塞线程同步。

下面是一个示例,说明如何使用Silverlight ProgressBar control 指示正在等待/处理对一个非常简单的 Silverlight Web 服务的调用:

Page.xaml:

<UserControl x:Class="SilverlightApplication1.Page"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
    Width="400" Height="100">

    <StackPanel x:Name="LayoutRoot" Background="White">
        <Button x:Name="ButtonDoWork" Content="Do Work"
                Click="ButtonDoWork_Click"
                Height="32" Width="100" Margin="0,20,0,0" />
        <ProgressBar x:Name="ProgressBarWorking"
                     Height="10" Width="200" Margin="0,20,0,0" />
    </StackPanel>
</UserControl>

Page.xaml.cs:

using System.ComponentModel;
using System.Windows;
using System.Windows.Controls;
using SilverlightApplication1.ServiceReference1;

namespace SilverlightApplication1
{
    public partial class Page : UserControl
    {
        public bool IsWorking
        {
            get { return ProgressBarWorking.IsIndeterminate; }
            set { ProgressBarWorking.IsIndeterminate = value; }
        }

        public Page()
        {
            InitializeComponent();
        }

        private void ButtonDoWork_Click(object sender, RoutedEventArgs e)
        {
            Service1Client client = new Service1Client();
            client.DoWorkCompleted += OnClientDoWorkCompleted;
            client.DoWorkAsync();

            this.IsWorking = true;
        }

        private void OnClientDoWorkCompleted(object sender, AsyncCompletedEventArgs e)
        {
            this.IsWorking = false;
        }
    }
}

在异步调用 DoWork 后将 IsIndeterminate 设置为 true 会使进度条像这样不确定地动画:

alt text http://www.freeimagehosting.net/uploads/89620987f0.png

因为对 OnClientDoWorkCompleted 的回调发生在 UI 线程上,所以可以在方法主体中将 IsIndeterminate 属性的值改回 false;随着工作/等待现在完成,这将再次导致非动画空白 ProgressBar。

下面是Web服务的代码和上面代码异步调用的DoWork方法,它所做的只是通过休眠5秒来模拟一些长时间运行的任务:

using System;
using System.ServiceModel;
using System.ServiceModel.Activation;
using System.Threading;

namespace SilverlightApplication1.Web
{
    [ServiceContract(Namespace = "")]
    [AspNetCompatibilityRequirements(RequirementsMode = AspNetCompatibilityRequirementsMode.Allowed)]
    public class Service1
    {
        [OperationContract]
        public void DoWork()
        {
            Thread.Sleep(TimeSpan.FromSeconds(5.0));
            return;
        }
    }
}

【讨论】:

  • 谢谢,我一定会试试的。直到我需要在 IsWorking 变量周围添加某种同步(锁定)并将其设置为 int。这是因为会有并行的异步请求,并且动画应该一直持续到所有调用完成。
猜你喜欢
  • 1970-01-01
  • 2013-03-01
  • 2018-07-27
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-06-01
相关资源
最近更新 更多