VB.NET 4.0: ThreadStatic не является потокобезопасным для моего свойства TdConnection - PullRequest
1 голос
/ 23 ноября 2011

Вот мой код:

<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 ]

2 голосов
/ 23 ноября 2011

Вы должны иметь одно соединение на запрос вместо одного на поток.

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

1 голос
/ 05 декабря 2012

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

...