Как обнаружить ожидающие асинхронные вызовы wcf? - PullRequest
3 голосов
/ 20 февраля 2009

Я звоню в службу WCF из своего приложения silverlight. Я делаю это асинхронно, и я не блокирую выполнение после выполнения асинхронного. call (это означает, что я не использую механизм ожидания соединения от этой страницы ). Я не хочу, чтобы поток был заблокирован.

Тем не менее, я хотел бы обнаружить, что вызов WCF перешел в состояние ожидания, чтобы я мог показать значок «занят» в пользовательском интерфейсе - визуальное сообщение, указывающее, что за пользовательским интерфейсом что-то происходит.

Я могу изменить свой код так, чтобы я мог начать анимировать значок «занято» и остановить эту анимацию после завершения асинхронного вызова.

Тем не менее, это много более жирного кода, и с увеличением количества обращений к клиентскому коду это только усложняется.

Итак, есть ли какой-либо метод или свойство, предоставляемые ссылочным кодом клиента службы wcf, которые можно использовать для запуска событий отключения, когда любые вызовы асинхронной службы wcf переходят в состояние ожидания, а также для запуска событий, когда все асинхронные wcf вызовы службы заканчиваются?

1 Ответ

4 голосов
/ 20 февраля 2009

В сгенерированном ссылочном классе клиента нет свойства или события, которое можно использовать для определения того, что асинхронный вызов метода службы Silverlight WCF в данный момент выполняется . Вы можете записать это самостоятельно, используя простую логическую переменную, или используя синхронизирующую блокировку потоков, которую вы упомянули, которую вы хотите избежать в этом случае.

Вот пример того, как сделать то, что вы хотите, с помощью элемента управления Silverlight ProgressBar , чтобы указать ожидание / работу над вызовом очень простого веб-сервиса Silverlight:

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

Установка IsIndeterminate в true после того, как асинхронный вызов DoWork заставляет индикатор выполнения анимироваться неопределенно следующим образом:

альтернативный текст http://www.freeimagehosting.net/uploads/89620987f0.png

Поскольку обратный вызов OnClientDoWorkCompleted происходит в потоке пользовательского интерфейса, можно изменить значение свойства IsIndeterminate обратно на false в теле метода; это приводит к тому, что ProgressBar снова не анимируется, поскольку работа / ожидание завершена.

Ниже приведен код для веб-службы и метода 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;
        }
    }
}
...