如何检测等待的异步wcf调用?

时间:2009-02-20 05:50:56

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

我从Silverlight应用程序调用WCF服务。 我异步执行此操作,并且在执行异步后我没有阻止执行。 call(这意味着,我没有使用等待连接机制frm this page)。我不希望流量被阻止。

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

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

然而,这是很多bolierplate代码,并且在整个客户端代码中进行了更多调用,这只会变得更加混乱。

那么,是否存在由wcf服务客户端引用代码公开的任何方法或属性,可用于在任何异步wcf服务调用进入等待状态时触发事件,同样,当all async wcf触发事件时服务电话结束了吗?

1 个答案:

答案 0 :(得分:4)

生成的客户端引用类上没有属性或事件可用于标识对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;
        }
    }
}