簡體   English   中英

通過Response.End()在ASP.NET中創建和中止線程有什么害處嗎?

[英]Is there any harm in creating and aborting a thread in ASP.NET via Response.End()?

我需要進行COM調用,並且只想等待x秒才能返回調用。 如果呼叫沒有在x秒內返回,我想結束請求。

創建一個Thread來進行調用。

string output = null;
Thread t = new Thread(() => { output = SomeHelper.DoWork(); });
t.Start();
t.Join(timeout);

if (string.IsNullOrEmpty(output))                
     this.Send500();

結束響應的方法。

protected void Send500()
{
    Response.ClearHeaders();
    Response.ClearContent();
    Response.Status = "500 ServiceUnavailable";
    Response.StatusCode = 500;
    Response.Flush();
    Response.SuppressContent = true;
    Response.End();
}

Response.End()觸發時,我得到一個Thread was being aborted錯誤。 這是預料之中的。 我錯了。 對於我正在嘗試做的事情,這沒關系。

當我需要注意這個錯誤時,還有其他原因需要注意嗎?

通常,Thread.Abort是非常邪惡的,但是中止自己的線程是安全的。 中止線程是危險的,因為中止可能發生在任何兩個指令之間。 但是,在一個明確定義的點上中止自己的線程。 這使后果可預測。

您沒有中止正在執行可能超時的工作的線程。 這很好,因為這將是一次非合作中止。 您冒着許多后台線程積累並耗盡一些資源的風險。 但如果這種風險是可以忍受的,你就可以了。 如果不能容忍,請將調用包裝到Semaphore如同步區域)中的COM服務,以限制最大資源使用量。

我會說你使用Response.Flush是有問題的,因為很少需要將字節刷新到客戶端。 這對我來說就像一個迷信的Flush

當我需要注意這個錯誤時,還有其他原因需要注意嗎?

您的主響應線程被ASP.NET中止(請參閱Response.End實現 )。 您為COM對象啟動的t線程保持活動狀態,只要SomeHelper.DoWork()返回或Web應用程序的AppDomain被回收。 這是否是一個問題取決於DoWork()內部發生了什么,但從長遠來看,它可能會損害您的服務器可擴展性,至少。

即使你調用t.Abort() (這絕不是一個好主意),在非托管調用返回之前, t線程不會被中止。

我寧願將SomeHelper.DoWork()移動到一個單獨的進程,只要沒有其他方法可以優雅地取消此調用,就可以輕松殺死/重新啟動它。 也許,實現這個的最簡單方法是通過注冊一個幫助DLL服務器進行代理激活來使你的COM對象處於進程外 您可能需要幫助程序“工廠”COM對象來創建SomeHelper並在需要時SomeHelper代理主機進程。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM