これが私のコードです:
<ThreadStatic()>
Dim _GlobalConnection As TdConnection
Public Property GlobalConnection As TdConnection
Get
If _GlobalConnection Is Nothing Then
_GlobalConnection = New TdConnection
End If
If _GlobalConnection.State <> ConnectionState.Open Then
OpenConnection(_GlobalConnection)
End If
Return _GlobalConnection
End Get
Set(ByVal value As TdConnection)
_GlobalConnection = value
End Set
End Property
これは ASP.NET Web アプリ内のモジュールにあるため、すべてのメンバーは定義上共有/静的です。ここでの私の目標は本質的に怠惰です。私はどこでも接続を使用するので、使用するたびに新しい接続オブジェクトを淡色表示にするのではなく、スレッドごとに新しいインスタンスとして機能するように、スレッド静的なプロパティを 1 つ持つことは理にかなっています。
これは、同じページを 2 つの別々のブラウザーにロードすることを決定するまでは機能していたようです。これを行うと、接続オブジェクトが既に使用されていることを示す例外がスローされます。
インスタンス タイプがスレッド セーフであるとは限らないという Microsoft の記事を読みました。この場合、このプロパティとそのフィールドがスレッドセーフであることを確認するにはどうすればよいですか?
編集:混乱しているのは、このコードがページ読み込みイベント内で機能することです:
Dim Tasks As New List(Of Task)
Tasks.Add(Task.Factory.StartNew(Sub() ucEmployee.LoadData()))
Tasks.Add(Task.Factory.StartNew(Sub() ucSales.LoadData()))
Tasks.Add(Task.Factory.StartNew(Sub() ucServers.LoadData()))
Tasks.Add(Task.Factory.StartNew(Sub() ucApps.LoadData()))
Task.WaitAll(Tasks.ToArray())
これらの .LoadData() メソッドはそれぞれ別のスレッドで実行され、すべて上記の GlobalConnection プロパティを参照します。最初は ThreadStatic 属性なしですべてを書きました。エラーが発生した後、GlobalConnection プロパティを ThreadStatic にすると、問題は解決しました。これが本番環境にロールアウトされると、この Web アプリは複数のユーザーによって使用されます。これが、2 つの Web ブラウザーで同じページを開くように促した理由です。そこには2つの別々のスレッドがあると思っていましたが、おそらくそれについては間違っています。