none
非同步的方法 與 回傳值的問題 RRS feed

  • 問題

  • 我有一個別人寫的 Library ,不能修改這個Library,其中有個方法叫 lib_function

    這個方法是 非同步 的,做完會呼叫 LibraryCallBack 這個Event 

    但是我的 Main 主程式必須獲得 這些Event 回傳的 全部資料,才能繼續我的工作

    請問 我有甚麼比較好的方法,可以去確認我一定可以獲得我要的資料  ?


    目前我沒甚麼頭緒,想用 lock ,我又不知道該 Lock 啥

    另外還在思考,是不是該讓主程序該每隔幾毫秒 檢查資料完整 和 睡覺 一下,來確定資料完整

    以下是我的 Sample code 

    using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading; namespace ConsoleApplication7 { class Program: LibraryEvent { static string SaveStr = ""; static void Main(string[] args) { SaveStr = ""; string[] country = new string[3]; country[0] = "tw,jp,hk,cn,kr"; country[1] = "us,ca"; country[2] = "es,fr,de"; Library Lib = new Library(); for( int i = 0;i<country.Length;i++) { Lib.lib_function(country[i] , this); } /* * 以下程式碼 必須確認 拿到全部的 Data 才能繼續..... */ } public void LibraryCallBack( string Data ) { // lib_function 做完 呼叫的 Event ...... 並把做完的資料傳入

    SaveStr += Data + ";"; } } }

    2014年3月24日 上午 11:44

解答

  • Hi, 并不需要Thread.Sleep,關鍵是在Lib.lib_function之後開始WaitOne,而且必須在拿完所有資料后才Set,這時有兩種可能:
    1,如果在WaitOne后一段時間才拿完所有資料,這時,在拿完所有資料呼叫Set之前,你的程序會一直停留在WaitOne那裡,不會繼續
    2,如果在呼叫WaitOne之前已經拿完所有資料並且呼叫了Set,這時,你的程序不會在WaitOne那裡停留(因為早已經Set了),但是沒關係,因為所有資料已經拿完了

    但是從你的程序來看,你會同時呼叫多次Lib.lib_function,所以你應該是想等待所有Lib.lib_function拿回資料后再繼續,這時如果用ManualResetEvent有點不太合適,因為一般只用ManualResetEvent來等待一個任務,如果要同時等待多個任務,建議使用CountdownEvent,請看這裡:
    http://msdn.microsoft.com/zh-tw/library/dd997365(v=vs.110).aspx
    http://msdn.microsoft.com/zh-tw/library/system.threading.countdownevent(v=vs.110).aspx

    2014年3月25日 上午 03:22

所有回覆

  • Hi, 你可以使用ManualResetEvent,請看:

    http://msdn.microsoft.com/zh-tw/library/system.threading.manualresetevent.aspx

    在主程序呼叫lib_function後,用ManualResetEvent.WaitOne()來等待,在LibraryCallBack裡面,獲取全部資料後用ManualResetEvent.Set來取消等待即可。


    • 已編輯 lapheal 2014年3月24日 下午 12:17
    2014年3月24日 下午 12:16
  • 題外話: 被發現我的 sample code 有問題 ....(嚇)

    TO :  lapheal

    這個方法 還是得 Thread.Sleep 吧 ?

    我拿 msdn 的 測試code 去修改測試,發現如果它加入的 thread 執行比較久

    而且還沒跑到 WaitOne(),Mail 主程式就 set() , 一樣會有資料來不急丟回去的情況

    但是我這個 Library 的方法就是無法確定 啥時候跑完.....(依據資料量的不同,速度也不一樣) 

    2014年3月25日 上午 02:33
  • Hi, 并不需要Thread.Sleep,關鍵是在Lib.lib_function之後開始WaitOne,而且必須在拿完所有資料后才Set,這時有兩種可能:
    1,如果在WaitOne后一段時間才拿完所有資料,這時,在拿完所有資料呼叫Set之前,你的程序會一直停留在WaitOne那裡,不會繼續
    2,如果在呼叫WaitOne之前已經拿完所有資料並且呼叫了Set,這時,你的程序不會在WaitOne那裡停留(因為早已經Set了),但是沒關係,因為所有資料已經拿完了

    但是從你的程序來看,你會同時呼叫多次Lib.lib_function,所以你應該是想等待所有Lib.lib_function拿回資料后再繼續,這時如果用ManualResetEvent有點不太合適,因為一般只用ManualResetEvent來等待一個任務,如果要同時等待多個任務,建議使用CountdownEvent,請看這裡:
    http://msdn.microsoft.com/zh-tw/library/dd997365(v=vs.110).aspx
    http://msdn.microsoft.com/zh-tw/library/system.threading.countdownevent(v=vs.110).aspx

    2014年3月25日 上午 03:22