2012-12-10 127 views
5

我想寫的異步代碼一個非常簡單的一點。我有一個void方法,它不會接受任何參數,它將從Windows服務中調用。我想將它踢開異步,這樣服務就不必等待方法完成。爲什麼沒有這個C#4.0異步方法被調用?

我創建了一個非常簡單的測試程序,以確保我在做編碼權,但異步方法只是不會被調用。任何人都能看到我做錯了什麼?順便說一句,我使用.NET 4.0,所以我不能使用await(這會更簡單!)。

這裏是我的整個測試樣本...

using System; 
using System.Threading; 

namespace AsyncCallback { 
    internal class Program { 
    private static void Main(string[] args) { 
     Console.WriteLine(DateTime.Now.ToLocalTime().ToLongTimeString() + " - About to ask for stuff to be done"); 
     new Action(DoStuff).BeginInvoke(ar => StuffDone(), null); 
     Console.WriteLine(DateTime.Now.ToLocalTime().ToLongTimeString() + " - Asked for stuff to be done"); 
    } 

    private static void StuffDone() { 
     Console.WriteLine(DateTime.Now.ToLocalTime().ToLongTimeString() + " - Stuff done"); 
    } 

    private static void DoStuff() { 
     Console.WriteLine(DateTime.Now.ToLocalTime().ToLongTimeString() + " - Starting to do stuff"); 
     Thread.Sleep(1000); 
     Console.WriteLine(DateTime.Now.ToLocalTime().ToLongTimeString() + " - Ending doing stuff"); 
    } 
    } 
} 

感謝所有幫助你可以給。之前,異步方法在ThreadPool被部署

+0

@馬丁:哪來的'async' /'await'在上面的問題? – spender

+0

爲什麼不使用.NET 4.5? – Rafael

+0

@spender與「C#」關鍵字相反,他使用「異步」作爲「異步」的通用縮寫。 – Servy

回答

6

您的程序終止。讓程序保持打開狀態。也許Console.ReadKey()Main結束了嗎?

+0

杜,真的很明顯!感謝那。我在一個測試項目中這樣做,所以在異步調用之後沒有發生任何其他事情。忘記線程會完全結束。謝謝。 –

5

任何應用程序將盡快沒有前景線程尚未完成執行結束。如果有任何後臺線程,他們將不會保持該進程「活着」。

由於您在後臺啓動異步任務,並且沒有任何操作使前臺線程保持運行,整個過程正在退出。

你要麼需要在前臺線程運行的異步任務,而不是(這不能與BeginInvoke據我所知做,你需要創建一個新的Thread明確),或者做別的事情來阻止主線程直到完成。

+0

謝謝Servy,像spender,你回答了這個問題:) –

1

你是不是等待完成,所以嘗試這樣

Console.WriteLine(DateTime.Now.ToLocalTime().ToLongTimeString() + " - About to ask for stuff to be done"); 
var a = new Action(DoStuff); 
var iar = a.BeginInvoke(ar => StuffDone(), null); 
a.EndInvoke(iar); 
Console.WriteLine(DateTime.Now.ToLocalTime().ToLongTimeString() + " - Asked for stuff to be done"); 
+0

雖然如果你只是等待異步任務的結果,爲什麼開始異步的第一個地方... – Servy

1

東西剛開始時,你的回調是不是正確的委託......這應該是

public delegate void AsyncCallback(IAsyncResult ar); 

和你是

private static void StuffDone() 

只是改變它的東西是這樣的:

private static void StuffDone(IAsyncResult ar){} 

,然後在回調確保操作實際執行調用

EndInvoke 
AsyncState

像這樣

private static void StuffDone(IAsyncResult ar) 
{ 
    Action r = ar.AsyncState as Action; 
    r.EndInvoke(ar); 

    Console.WriteLine(DateTime.Now.ToLocalTime().ToLongTimeString() + " - Stuff done"); 
} 

還有一個變化,你需要要做的是,當你在主函數中實例化Action時,將動作本身作爲的'object'參數方法是這樣的:

Action d = new Action(DoStuff); 
d.BeginInvoke(StuffDone, d); 

這應該解決您的問題:)

相關問題