2013-10-15 208 views
0
public delegate string AsyncMethodCaller(int callDuration, out int threadId); 

class Program 
{ 
    static void Main(string[] args) 
    { 
     int threadId; 

     AsyncMethodCaller caller = new AsyncMethodCaller(TestMethod); 

     IAsyncResult result = caller.BeginInvoke(3000, 
      out threadId, new AsyncCallback(Callback), null); 

     Console.WriteLine("Main thread {0} does some work.", 
      Thread.CurrentThread.ManagedThreadId); 

     string returnValue = caller.EndInvoke(out threadId, result); 

     Console.WriteLine("The call executed on thread {0}, with return value \"{1}\".", 
      threadId, returnValue); 
    } 

    static public string TestMethod(int callDuration, out int threadId) 
    { 
     Console.WriteLine("Test method begins."); 
     Thread.Sleep(callDuration); 
     threadId = Thread.CurrentThread.ManagedThreadId; 
     return String.Format("My call time was {0}.", callDuration.ToString()); 
    } 

    static void Callback(IAsyncResult result) 
    { 
     int a = 5; 
     int b = 20; 

     int c = a + b; 

     Console.WriteLine(c + Environment.NewLine); 
    } 
} 

此代碼基本上異步執行TestMethod。但是我遇到的問題是在調用者調用EndInvoke之後,主線程停止並等待TestMethod完成作業。所以基本上整個應用程序都卡住了。這個過程可以是異步的嗎? ?我的意思是我想要的是調用一些方法異步,然後等待回調,但如果我刪除EndInvoke調用,然後CallBack沒有命中。這種情況下的最佳做法是什麼?異步委託調用和回調

+0

您的回調沒有被擊中,因爲主線程完成。這在GUI應用程序中通常不是問題,因爲UI線程始終在運行。你應該嘗試添加一個循環來模擬正在工作的主線程。這樣,當回調被調用時它仍然是活着的。 –

+1

這看起來就像是[異步調用同步方法](http://msdn.microsoft.com/en-us/library/2e08f6yc.aspx)中的確切示例,它表示**因爲EndInvoke可能會阻塞,所以您絕對不應該從服務用戶界面的線程調用它。**。稍後會顯示__執行異步調用完成時的回調方法___。但是,爲什麼不使用'TPL'? – Harrison

回答

0

您最好使用任務及其Task.Wait方法。 http://msdn.microsoft.com/ru-ru/library/dd321424.aspx

smthing這樣的:

var returnValue = Task<string>.Factory.StartNew(() => TestMethod()); 
+0

回調怎麼樣?當TestMethod完成執行時,我希望回調被擊中。 – Dimitri

+0

@Dima 有一個像這樣的東西http://msdn.microsoft.com/ru-ru/library/dd321474.aspx 試試類似這樣的: 'Task tsk = new Task(TestMethod); Tasl tskCont = tsk.ContinueWith(回調);無論如何,' –

+0

似乎都是關於TPL –