使用线程本地存储进行此操作安全吗?

Jef*_*eff 4 vb.net asp.net multithreading threadpool

我有一个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
Run Code Online (Sandbox Code Playgroud)

请注意,我不是在问LocalNamedDataStore插槽是否是线程安全的。根据定义,我知道它们是。

Jar*_*Par 5

在这种情况下,使用线程本地存储是安全的。没有两个线程将共享同一本地存储(因此它是本地线程)。因此,两个并发请求不会占用其他数据。

虽然还有其他一些评论

  • 请勿使用Thread.Abort。这是非常危险的操作,实际上这里不需要。该线程将在此之后结束该语句。
  • 更好的方法是创建一个类,该类包含具有UserId本地字段的后台操作。每个请求都会获得一个新的类实例。这是一种将数据传递到后台任务的简便得多的方法