在範例程式看到OperationContract(IsOneWay=true),不求甚解以為是指單向呼叫(傳回值是void)跟著亂抄亂用(錯誤示範,大家不要學),搞出一些奇怪現象才回頭查,發現觀念錯得離譜。
IsOneWay是用來定義單向合約沒錯,但重點在「呼叫端呼叫WCF作業,但不期待收到任何回應」,其真正意義更傾向「Fire and Forget」(射後不理)。因此,指定OperationContract(IsOneWay=true)的方法傳回值應為void,最重要的差別在於呼叫該方法後,不會等待作業完成就繼續往下執行。
用一個範例來驗證。IService1提供兩個方法,Delay5Seconds()及Delay5SecondsOneWay(),差在後者宣告為[OperationContract(IsOneWay=true)]:
using System.ServiceModel;
using System.Threading;
namespace WcfTest
{
[ServiceContract]
publicinterface IService1
{
[OperationContract]
void Delay5Seconds();
[OperationContract(IsOneWay = true)]
void Delay5SecondsOneWay();
}
publicclass Service1 : IService1
{
publicvoid Delay5Seconds()
{
Thread.Sleep(5000);
}
publicvoid Delay5SecondsOneWay()
{
Thread.Sleep(5000);
}
}
}
呼叫端程式如下:
staticvoid Main(string[] args)
{
var sc = new WcfTest.Service1Client();
Console.WriteLine("{0:HH:mm:ss.fff} Start", DateTime.Now);
sc.Delay5Seconds();
Console.WriteLine("{0:HH:mm:ss.fff} Mid", DateTime.Now);
sc.Delay5SecondsOneWay();
Console.WriteLine("{0:HH:mm:ss.fff} End", DateTime.Now);
Console.Read();
}
執行結果,呼叫DelaySeconds()時會等5秒程式才往下執行,而Delay5SecondsOneWay()則不等待Server端執行就繼續往下走。
因此,針對單純下達執行命令,結果或狀態會以其他管道回饋的作業,或是執行耗時的長期作業,可使用IsOneWay旗標滿足Client端的非同步需求。