让wcf客户端等待回调

时间:2017-03-01 07:47:32

标签: c# wcf

我目前正在开发一个项目,我必须通过wcf客户端管理应用程序。我面临的问题是,在调用服务器后,我需要客户端等待回调。这是场景:

我打电话给显示窗口的服务,然后服务器应用程序空闲。当我单击窗口上的按钮时,它会向客户端发出回调。在此期间,必须禁用客户端UI - 它必须等待回调。你能告诉我怎么做到这一点吗?是否与“并发模式”或“操作合同”属性有关?

这是我的ServiceContract和CallbackContract的代码:

[ServiceContract(CallbackContract = typeof(IWCFServiceCallback))]
public interface IWCFService
{
    [OperationContract]
    void OpenWindow();
}
public interface IWCFServiceCallback
{
    [OperationContract(IsOneWay = true)]
    void ReturnValue(object[] value);
}

4 个答案:

答案 0 :(得分:1)

不,您描述的功能与并发模式或操作合同无关。您可能需要使用信号量(MutexMonitor,无论......)以及从服务器到客户端的回调来实现该功能,以设置信号量。

说过你描述的功能似乎很奇怪。

答案 1 :(得分:1)

您可以通过实现异步服务操作并使用Async/Await调用它来完成此操作。

在调用服务之前禁用客户端UI,然后在回调返回后启用它。

https://msdn.microsoft.com/en-us/library/ms731177.aspx

using System;
using System.Collections.Generic;
using System.ServiceModel;
using System.Text;
using System.Threading;

namespace Microsoft.WCF.Documentation
{
  [ServiceContractAttribute(Namespace="http://microsoft.wcf.documentation")]
  public interface ISampleService{

    [OperationContractAttribute]
    string SampleMethod(string msg);

    [OperationContractAttribute(AsyncPattern = true)]
    IAsyncResult BeginSampleMethod(string msg, AsyncCallback callback, object asyncState);

    //Note: There is no OperationContractAttribute for the end method.
    string EndSampleMethod(IAsyncResult result);

    [OperationContractAttribute(AsyncPattern=true)]
    IAsyncResult BeginServiceAsyncMethod(string msg, AsyncCallback callback, object asyncState);

    // Note: There is no OperationContractAttribute for the end method.
    string EndServiceAsyncMethod(IAsyncResult result);
  }

  public class SampleService : ISampleService
  {
    #region ISampleService Members

    public string  SampleMethod(string msg)
    {
      Console.WriteLine("Called synchronous sample method with \"{0}\"", msg);
      return "The sychronous service greets you: " + msg;
    }

    // This asynchronously implemented operation is never called because 
    // there is a synchronous version of the same method.
    public IAsyncResult BeginSampleMethod(string msg, AsyncCallback callback, object asyncState)
    {
      Console.WriteLine("BeginSampleMethod called with: " + msg);
      return new CompletedAsyncResult<string>(msg);
    }

    public string EndSampleMethod(IAsyncResult r)
    {
      CompletedAsyncResult<string> result = r as CompletedAsyncResult<string>;
      Console.WriteLine("EndSampleMethod called with: " + result.Data);
      return result.Data;
    }

    public IAsyncResult BeginServiceAsyncMethod(string msg, AsyncCallback callback, object asyncState) 
    {
      Console.WriteLine("BeginServiceAsyncMethod called with: \"{0}\"", msg);
      return new CompletedAsyncResult<string>(msg);
    }

    public string EndServiceAsyncMethod(IAsyncResult r)
    {
      CompletedAsyncResult<string> result = r as CompletedAsyncResult<string>;
      Console.WriteLine("EndServiceAsyncMethod called with: \"{0}\"", result.Data);
      return result.Data;
    }
    #endregion
  }

  // Simple async result implementation.
  class CompletedAsyncResult<T> : IAsyncResult
  {
    T data;

    public CompletedAsyncResult(T data)
    { this.data = data; }

    public T Data
    { get { return data; } }

    #region IAsyncResult Members
    public object AsyncState
    { get { return (object)data; } }

    public WaitHandle AsyncWaitHandle
    { get { throw new Exception("The method or operation is not implemented."); } }

    public bool CompletedSynchronously
    { get { return true; } }

    public bool IsCompleted
    { get { return true; } }
    #endregion
  }
}

答案 2 :(得分:1)

当concurrenymode是ConcurrencyMode.Single并且客户端调用该服务时,该服务将创建一个锁。当它调用IsOneWay的回调接口为false时,结果消息将被发送回服务。该服务将再次创建锁定并将死锁,因为仍然从客户端调用保持锁定。 使用ConsurrencyMode。当重新回电并重新获得时,可以重新锁定该锁,这样您就可以使用它。 IsOneWay = true也是一个解决方案,因为没有结果消息被发送回服务回调。

因此,当回调操作具有IsOneWay = true或服务已配置ConcurrencyMode.Reentrant时,您应该能够在调用服务之前锁定GUI并在回调中解锁它

答案 3 :(得分:0)

感谢您的回答。我通过使用Win32 ShowWindow函数解决了这个问题。