2017-03-01 124 views
5

我目前正在開發一個項目,我必須通過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); 
} 

回答

0

謝謝您的回答。我通過使用Win32 ShowWindow函數解決了這個問題。

1

沒有,你所描述的功能無關併發模式或經營合同。您可能需要使用信號量(Mutex,Monitor,無論是...)還是從服務器到客戶端的回調來設置信號量。

說了你描述的功能似乎很奇怪。

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 
    } 
} 
+0

感謝您的回覆。我會在調用一個方法之後添加一個方法,我希望客戶端的行爲與方法本身返回值(不帶回調)相同 - 客戶端一直等到服務完成其工作並返回一個值。我無法手動鎖定UI,因爲客戶端是一個Excel插件,它沒有我可以禁用的窗體/窗口。 – Bartek

+0

在Excel打開FunctionWizard時調用服務,所以我不能鎖定單元格,因爲它會導致Excel崩潰。 – Bartek

+0

@Bartek - 然後,這是一個不同的問題,單獨的問答。我相信我已經提供了這個問題的答案,但是如果不讓我知道,我會盡力進一步提供幫助。僅供參考請注意,微軟在其示例代碼中偏離了其自己的[推薦命名約定](https://msdn.microsoft.com/en-us/library/mt674882.aspx#Anchor_7)。異步函數應該在其名稱後附加「Async」。當然,我們在這裏看不到'async'關鍵字,但這仍然是一個異步體系結構。 – InteXX

1

當concurrenymode是ConcurrencyMode.Single和客戶端調用服務,該服務將創建一個鎖。當它使用IsOneWay調用回調接口爲false時,結果消息將被髮送回服務。該服務將再次創建該鎖,並且會因爲仍然保持來自客戶端調用的鎖而導致死鎖。 With ConsurrencyMode。可重入的鎖定在回撥時會被偷偷地釋放,並在返回時重新獲取,以便您可以使用該鎖定。 IsOneWay = true也是一個解決方案,因爲沒有結果消息被送回服務回調。

所以,你應該能夠鎖定你的GUI只調用服務之前,並在回調解鎖回調時操作有IsOneWay = true或服務有ConcurrencyMode.Reentrant配置

+0

問題是我無法手動鎖定客戶端的UI,因爲它是打開了FunctionWizard的Excel AddIn。如果我嘗試鎖定單元格,Excel崩潰。 – Bartek