zoukankan      html  css  js  c++  java
  • Silverlight使用WebService,WCF,RIA Service的同步方法

    大多數接觸Silverlight程式開發的人只要有需要對後端Server作呼叫應該都會遇到一個問題,那就是所有的呼叫都是非同步機制,而沒有任何同步的方式,這個問題的主因在於Web機制上的問題,MSDN論壇中有很多篇已討論此問題且有介紹原因,但不幸的受限於底層.在Silverlight SDK中要做到同步會有些考量因素我想未來應該也很難加入,本篇文章在於如何解決這些問題.
    由於Silverlight呼叫並不能同步呼叫所以必須找到一些方式來處理,熟悉MultiThread設計的人第一個想到的就是透過dotNet的Thread同步機制來處理,譬如說Thread.Join或AutoEvent等方式.但一使用這個方法馬上出現個一個問題,並無法正常運作似乎程式碼凍結在那邊不會執行
    底下為範例程式碼 
                System.Threading.AutoResetEvent evt = new System.Threading.AutoResetEvent(false);
                this.DomainContext.SubmitChanges(
                   (op) =>
                   {
                       evt.Set();
                   }, null);
                evt.WaitOne();
    程式執行到evt.WaitOne就停在那不會動了,但這個方式在WPF或Winform中運作的很順利,似乎Silverlight有個原因而無法運作,而這個原因就是Silverlight無法非同步呼叫的主因,先來看看原因,就會了解該如何解決了. 
    看以下程式碼
        1             this.DomainContext.SubmitChanges(
        2                (op) =>
        3                {
        4                    .....
        5                }, null);
        6 
        7             ........
    以上是個一個非同步呼叫的範例程式碼,如果試著在4與7那行做中斷追蹤,會發現一個狀況,不論執行多少次,7永遠比4先執行.即使7後面還有更多的程式碼,不論如何增加,只要在同一個函式內都是一樣,故得到一個結論,在Silverlight中同一個函式內的非同步呼叫一定於函式執行完後才會執行,這也是上面evt.WaitOne會凍結在那的原因,因為evt.Set根本無會觸發.難道這個問題在所有Silverlight函式中都會發生?其實上面說法並不完全,如果在仔細閱讀MSDN論壇的原因,真正得到的結論是-
    在Silverlight中UI Thread中的函式執行非UI執行緒,則此執行緒一定於函式執行完後才會執行
    也就是說這只會發生在UI Thread,所以解決方式自然就出來的上述程式碼改為如下 
        1             new Thread(new ThreadStart(
        2                 () => 
        3                 {
        4                 AutoResetEvent evt = new AutoResetEvent(false);
        5                 this.DomainContext.SubmitChanges(
        6                    (op) =>
        7                    {
        8                        ....
        9                        evt.Set();
       10                    }, null);
       11 
       12                 evt.WaitOne();
       13                 ........
       14             })).Start();
    將原來的程式碼再包裝於另一個Thread中,即可解決此問題了.evt.WaitOne也能正常運作了.
     
     
    但因為這種方式在撰寫程式時變得相當麻煩,如過更複雜些的執行順序將會導致程式在撰寫實的複雜度,故我另外也寫了一個SerialisedWorkQueue輔助類別來處理間化這個問題,使用方式如同底下程式碼,會在後續文章中介紹 
               SerialisedWorkItem wi = new SerialisedWorkItem(
                    (o, set) => //段落一
                    {
                        this.IsBusy = true;
                        this.DomainContext.Load(this.DomainContext.GetDestributionPotentialsQuery(),
                               (op) =>
                               {
                                   …
                                   set();
                               }
                               , null);
                    }).Parallel( 
                    (o, set) => //段落二
                    {
                        this.DomainContext.Load(this.DomainContext.GetDamagePotentialsQuery(),
                            (op) =>
                            {
                                …
                                set();
                            }
                        , null);
                    }).After( //段落三
                    (o, set) =>
                    {
                        this.DomainContext.Load(this.DomainContext.GetMalwareInfosQuery().Where(m => m.Id == this._malwareInfoId),
                                    (op) =>
                                    {
                                        …
                                        this.IsBusy = false;
                                        set();
                                    }
                                , null);
                    });
     
                SerialisedWorkQueue workQueue = new SerialisedWorkQueue();
                workQueue.QueueWorkItem(wi);
    段落一跟段落二同時執行,然後兩者執行完後再執行斷落三.
    Powered By D&J (URL:http://www.cnblogs.com/Areas/)
  • 相关阅读:
    【Rust】结构体 struct
    【Rust】所有权、引用、借用
    Centos7升级glibc2.24
    ES用户权限控制
    PHP压缩html网页代码 : 清除空格,制表符,注释标记
    PHP通过HTTP_USER_AGENT判断是否为手机移动终端的函数
    php正则表达式替换URL链接地址为指定url的形式
    PHP下使用CURL方式POST数据至API接口的方法
    设计模式代理模式
    设计模式生成器模式
  • 原文地址:https://www.cnblogs.com/Areas/p/2174459.html
Copyright © 2011-2022 走看看