VB.NET 4.0: ThreadStatic не является потокобезопасным для моего свойства TdConnection

Вот мой код:

<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, поэтому все члены являются общими / статическими по определению. Моя цель здесь по сути лень. Я использую соединения везде, поэтому просто имело смысл иметь одно свойство, которое является статическим потоком, чтобы оно служило новым экземпляром для каждого потока, вместо того, чтобы затемнять новый объект подключения каждый раз, когда я хочу его использовать.

Кажется, это работало, пока я не решил загрузить одну и ту же страницу в двух разных браузерах. Когда я делаю это, генерируется исключение, в котором говорится, что объект подключения уже используется.

Я прочитал в статье 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, и проблема исчезла. Когда он будет запущен в производство, этим веб-приложением будут пользоваться несколько человек. Именно это побудило меня открыть одну и ту же страницу в двух веб-браузерах. Я думал, что это были бы две отдельные темы, но, возможно, я ошибаюсь в этом.

2 ответа

Решение

У вас должно быть одно соединение на запрос, а не одно на поток.

Для этого сохраните его в HttpContext.Current.Items вместо поля ThreadStatic.
Вы также должны закрыть соединение в EndRequest обработчик.

Это не работает, потому что это не staticдолжно быть static для ThreadStatic атрибут для применения

Другие вопросы по тегам