在範例程式看到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]
    public interface IService1
    {
 
        [OperationContract]
        void Delay5Seconds();
        [OperationContract(IsOneWay = true)]
        void Delay5SecondsOneWay();
    }
 
    public class Service1 : IService1
    {
 
        public void Delay5Seconds()
        {
            Thread.Sleep(5000);
        }
 
        public void Delay5SecondsOneWay()
        {
            Thread.Sleep(5000);
        }
    }
}

呼叫端程式如下:

        static void 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端的非同步需求。


Comments

Be the first to post a comment

Post a comment