Make wcf client wait for callback

I am currently working on a project where I need to manage an application through a wcf client. The problem I am facing is that after making a call to the server, I need the client to expect a callback to be made. Here is the scenario:

I make a service call that shows a window and then the server application is down. When I click the button in the window, it makes a callback to the client. over time, the client user interface must be disconnected - it must wait for a callback. Could you tell me how I can achieve this? Does it have anything to do with the Concurrency mode or the Operation Contract attribute?

This is my code for ServiceContract and CallbackContract:

[ServiceContract(CallbackContract = typeof(IWCFServiceCallback))] public interface IWCFService { [OperationContract] void OpenWindow(); } public interface IWCFServiceCallback { [OperationContract(IsOneWay = true)] void ReturnValue(object[] value); } 
+5
source share
4 answers

Thank you for your responses. I solved the problem using the Win32 ShowWindow function.

0
source

No, the function you are describing has nothing to do with Concurrency mode or an operating contract. You probably need to implement this function using semaphores ( Mutex , Monitor , whatever ...) and callbacks from server to client to set the semaphore.

Having said that, the functionality you describe seems very strange.

+1
source

You can do this by performing an asynchronous service operation and calling it using Async/Await .

Disable the client user interface just before calling your service, and then enable it after the callback returns.

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 } } 
+1
source

When concurrenymode is ConcurrencyMode.Single and the client calls the service, the service will create a lock. When it calls the callback interface with IsOneWay, false, the result message will be sent back to the service. The service will create the lock again and close because the lock is saved from the client call. With ConsurrencyMode. The reentrant lock will be discreetly released upon callback and return to return so you can use it. IsOneWay = true is also a solution, since no result message is sent back back.

Thus, you should be able to lock your 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

+1
source

Source: https://habr.com/ru/post/1264868/


All Articles