当您处理标准 FORMS 或 CMD Line 应用程序时,假设您不创建任何显式线程并且不使用任何暗示单独线程(如后台工作程序)的组件,那么您将在主应用程序线程上操作所有正常输入的用户代码. 系统将创建其他线程来执行各种操作以支持您的应用程序,但出于所有密集目的,您可以认为它是线程安全的。还有其他线程将是 otehr 组件的一部分,并且应该已经以安全的方式进行编码,以便在没有任何冲突或跨线程问题的情况下进行交互。
正如您所指出的,在 ASP.NET 中这是不同的。除了特定页面之外,IIS 并不真正关心您创建的对象。您的主线程是针对给定请求的,实际上主要对象是“页面”,页面中存储的任何内容都位于这种没有冲突可以真正解决的隐蔽空间中。也是会话对象,这是特定于页面的,并且尽可能与特定请求隔离,因此是安全的。从来没有一个 Page 或 Session 对象暴露给另一个,但是这些页面都在同一个应用程序中,并且从技术上讲可以相互看到(除非你做了一些非常奇怪的编码,这肯定会非常非常糟糕)。
在更大程度上变得不安全的是应用程序对象。如果您将对象存储在应用程序空间中并在多个页面请求中使用它,您需要确保您对对象所做的任何事情都不会与可以在并行请求中处理的另一个请求发生冲突。这方面的一个例子可以是在应用程序空间中存储项目的静态数据表。但是,如果您必须采用一种安全的方法来处理它,我通常不会这样做,那就是使用同步对象来不允许来自一个请求/线程的代码与该对象重叠。另请注意,应用程序对象/空间实际上与 VB.Net 中的公共模块空间相同,我使用一个模块来显示下面的示例......
示例 (这是非常简化的,而不是我通常在代码中做的事情,它只是为了解释 SYNCLOCK 机制)
Public Module SharedSpace
' what object is used as a syncronizer is irrelavent, just needs defined only once at the start of the application.
Public SyncDT As New Exception("none")
Public dt As DataTable
End Module
Public Class PageItem
Inherits System.Web.UI.Page
Private Sub Page_Load(sender As Object, e As System.EventArgs) Handles Me.Load
SyncLock SyncDT
' ...
' work with "dt" ONLY inside the synclock space
' SyncLock blocks can be anywhere but they need to be as short as possible.
' Any code running in another page request will STOP trying to enter the SyncLock (for the object specified)
' and waits until any existing SyncLock on the same object is released by exiting the SyncLock.
' ...
End SyncLock
End Sub
End Class
实际上,只要“dt”仅在具有“Synclock SyncDT”的块内访问,它在多个线程之间是安全的。但是,以这种方式在没有 SyncLock 的情况下访问“dt”是不可接受的,因为可能会发生重叠。
.NET 中还有其他线程编组对象,Synclock 是我的首选。