简体   繁体   English

让wcf客户端等待回调

[英]Make wcf client wait for the callback

I'm currently working on a project, where I have to manage an application via a wcf client. 我目前正在开发一个项目,我必须通过wcf客户端管理应用程序。 The problem I'm facing is that after making a call to the server I need the client to wait for the callback to be made. 我面临的问题是,在调用服务器后,我需要客户端等待回调。 Here is the scenario: 这是场景:

I make a call to the service which shows a window and then the server app is idle. 我打电话给显示窗口的服务,然后服务器应用程序空闲。 When i click a button on the window, it makes a callback to the client. 当我单击窗口上的按钮时,它会向客户端发出回调。 during the time, the client UI has to be disabled - it has to wait for the callback. 在此期间,必须禁用客户端UI - 它必须等待回调。 Could you please tell me how I can achieve this? 你能告诉我怎么做到这一点吗? Does it have something to do with Concurrency Mode or the Operation Contract attribute? 是否与“并发模式”或“操作合同”属性有关?

This is my code for the ServiceContract and the CallbackContract: 这是我的ServiceContract和CallbackContract的代码:

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

No, the feature you describe has nothing to do with Concurrency Mode or the Operation Contract. 不,您描述的功能与并发模式或操作合同无关。 You probably need to implement the feature using semaphores ( Mutex , Monitor , whatever ...) and callbacks from server to client to set the semaphore. 您可能需要使用信号量( MutexMonitor ,等等......)以及从服务器到客户端的回调来实现该功能以设置信号量。

Having said that the functionality you describe seems really odd. 说过你描述的功能似乎很奇怪。

You can do this by implementing an asynchronous service operation and calling it using Async/Await . 您可以通过实现异步服务操作并使用Async/Await调用它来完成此操作。

Disable your client UI just before calling your service, and then enable it after the callback returns. 在调用服务之前禁用客户端UI,然后在回调返回后启用它。

https://msdn.microsoft.com/en-us/library/ms731177.aspx 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
  }
}

When the concurrenymode is ConcurrencyMode.Single and the client calls the service, the service will create a lock. 当concurrenymode是ConcurrencyMode.Single并且客户端调用服务时,该服务将创建一个锁。 When it calls the callback interface with IsOneWay is false a result message will be sent back to the service. 当它调用IsOneWay的回调接口为false时,结果消息将被发送回服务。 The service will create the lock again and will deadlock because the lock is held from the client call still. 该服务将再次创建锁定并将死锁,因为仍然从客户端调用保持锁定。 With ConsurrencyMode. 使用ConsurrencyMode。 Reentrant the lock will sneakily be released when calling back and reacquired on return so you could use that. 当重新回电并重新获得时,可以重新锁定该锁,这样您就可以使用它。 IsOneWay=true is also a solution as no result message is sent back the service calling back. IsOneWay = true也是一个解决方案,因为没有结果消息被发送回服务回调。

So you should be able to lock you GUI just before calling the service and unlock it in the callback when the callback operation has IsOneWay = true or the service has ConcurrencyMode.Reentrant configured 因此,当回调操作具有IsOneWay = true或服务已配置ConcurrencyMode.Reentrant时,您应该能够在调用服务之前锁定GUI并在回调中解锁它

Thanks for your answers. 谢谢你的回答。 I solved the problem by using the Win32 ShowWindow function. 我通过使用Win32 ShowWindow函数解决了这个问题。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM