2011-11-29 22 views
3

我有一個允許最終用戶上傳文件的ASP.NET Web應用程序。一旦文件在服務器上,我就產生一個線程來處理文件。該線程傳遞有關特定操作的數據(UserId,文件路徑,各種選項等)。大部分數據都是通過對象和方法參數傳遞的,但是UserId需要全局更多,所以我把它放在線程本地存儲中。是否使用線程本地存儲安全進行此操作?

線程很長,但它只是處理文件並中止。在這種情況下,我使用指定的數據插槽是否安全? 如果UserA上傳文件,則UserB在第一個文件仍在處理時上載文件,是否有可能UserA的線程也將被委派處理UserB,從而對指定的插槽產生衝突?(即插槽被UserB的id覆蓋,UserA文件的其餘操作鏈接到錯誤的User,UserB)。

Public Class FileUploadProcess 
    Public UserId as String 

    Public Sub ExecuteAsync() 
     Dim t As New Thread(New ThreadStart(AddressOf ProcessFile)) 
     t.Start() 
    End Sub 

    Protected Sub ProcessFile() 
     Dim slot As LocalDataStoreSlot = Thread.GetNamedDataSlot("UserId") 
     Thread.SetData(slot, UserId) 

     'lengthy operation to process file 

     Thread.FreeNamedDataSlot("UserId") 
     Thread.CurrentThread.Abort() 
    End Sub 
End Class 

我如果LocalNamedDataStore插槽是線程安全不是問。根據定義,我知道他們是。

回答

4

在這種情況下,您使用線程本地存儲是安全的。沒有兩個線程會共享相同的本地存儲(因此它是線程本地的)。所以兩個併發請求不可能踩到其他數據。

夫婦的其他意見,雖然

  • 請避免使用Thread.Abort。這是一個非常危險的操作,如實地不需要這裏。之後線程將結束語句。
  • 更好的方法是創建一個包含後臺操作的類,該後臺操作將UserId作爲本地字段。每個請求都會獲得一個新的類實例。這是將數據傳遞到後臺任務的更簡單的方法
+2

+1避免Thread.Abort –

+0

是否有可能一個線程一次可以處理多個文件?對不起,如果你回答了這個問題,或者如果這沒有意義,但實際上多線程是有點超越我。 – Jeff

+0

@Jeff給出簡短的代碼示例我會說不。它看起來每個線程都是專用於單個文件 – JaredPar

1

這是安全操作。

我不得不說,我是JaredPars認爲,這將是最好創建一個類和用戶ID存儲在該類作爲一個字段是不完整的,至少可以說。

你在哪裏存儲該對象?由於它是根據請求創建的,因此您必須將其存儲在某個地方。您是否將該頁面與此功能結合在一起?我不會。你是否存儲在Context.Items集合中?這是一種可能性,但是如果你想從ASP.Net中提取代碼,你會怎麼做單元測試,這樣可以測試更多的代碼呢?

我個人完成了兩種方法的混合:我創建了一個包含所有請求特定數據元素的類,然後在線程本地存儲器中緩存該對象。這允許代碼在單元測試框架中運行,而不必模擬ASP.Net運行時環境。

另一個重要的問題是:如果你打算在ASP.Net中使用異步模式,你應該知道TLS在將執行上下文切換到新線程時不會轉發到新線程。它確實是「線程本地」。

+1

謝謝Brian。這裏有幾個好點可供思考。你什麼時候通過TLS訪問緩存的對象而不是通過方法參數傳遞數據? – Jeff

相關問題