我有一個Web服務方法FetchNumber(),其獲取來自數據庫的數,然後返回給調用者。但在它將號碼返回給調用者之前,它需要將此號碼發送到另一個服務,以便實例化並運行BackgroundWorker,其工作是將此號碼發送到另一個服務。Web服務進行異步調用
public class FetchingNumberService : System.Web.Services.WebService
{
[WebMethod]
public int FetchNumber()
{
int value = Database.GetNumber();
AsyncUpdateNumber async = new AsyncUpdateNumber(value);
return value;
}
}
public class AsyncUpdateNumber
{
public AsyncUpdateNumber(int number)
{
sendingNumber = number;
worker = new BackgroundWorker();
worker.DoWork += asynchronousCall;
worker.RunWorkerAsync();
}
private void asynchronousCall(object sender, DoWorkEventArgs e)
{
// Sending a number to a service (which is Synchronous) here
}
private int sendingNumber;
private BackgroundWorker worker;
}
我不想阻止Web服務(FetchNumber())在發送這個號碼到另一個服務,因爲它需要很長的時間,主叫方不會關心發送的數量到另一個服務。來電者希望這個儘快返回。
FetchNumber()使得後臺工作,並運行它,然後完成(而工人在後臺線程中運行)。我不需要任何進度報告或後臺工作人員的返回值。這更多是一個難忘的概念。
我的問題是這樣的。由於Web服務對象是每個方法調用實例化的,當被調用的方法(在這種情況下爲FetchNumber())完成時會發生什麼,而它安裝並運行的後臺工作器仍在運行?
會發生什麼事到後臺線程? GC何時收集服務對象?這是否會阻止後臺線程正確執行到最後?後臺線程有沒有其他副作用?
感謝任何輸入。
如果BackgroundWorker只是AsyncUpdateNumber的構造函數的方法範圍的局部變量,而不是其字段?對我來說,重要的問題不僅是這些對象是否會被收集,而且即使起始線程沒有引用後臺工作線程,線程是否會完成其工作? – 2010-05-31 20:39:50
當您在AsyncUpdateNumber類的構造函數中啓動worker時,該方法將完成。但是,由於所有調用都會創建永遠不會收集的新對象,因此會創建內存泄漏。如果*有*使用BackgroundWorker,只要Worker已經啓動,您應該立即從BackgroundWorker註銷事件實例。方法完成後,將BackgroundWorker設置爲null。不過,我認爲這是漫長的...看樣品和簡單。 – AxelEckenberger 2010-05-31 20:54:14
我不能這樣做,因爲我需要把作業的異步部分分成一個類(用於可重用性問題)。我可能會把你的樣本放入一個班級,但這也讓我面對原始問題。由於第一個線程只創建一個Async類的實例作爲局部變量,所以當它離開作用域時(即方法結束),它應該被刪除。當其他線程完成其工作時(無論是BW,Thread,BeginInvoke還是Pool),會發生什麼情況。 GC是否爲每個線程都有單獨的參考樹? – 2010-06-01 06:37:37