жизнеспособное решение этой проблемы? - PullRequest
2 голосов
/ 22 марта 2011

Я звоню из одного куска моего кода через несколько уровней стороннего кода, и в какой-то момент этот вызов возвращается в мой код, вызывая некоторый код, который я написал.

Другими словами, цепочка кодовых вызовов выглядит следующим образом:

My code #1 --> 3rd party code --> My code #2

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

Так что мне было интересно, если бы просто использование [ThreadStatic] для статического поля в классе было бы жизнеспособным решением этой проблемы?

Поскольку код также выполняется в веб-приложении, я не могу просто использовать для этого статическое поле, поскольку значение, к которому мне нужен доступ (объект), отличается для каждого пользователя / сеанса.

т. Я бы сделал что-то вроде этого:

internal static class DataHolder
{
    [ThreadStatic]
    internal static ClassName FieldName;
}

Есть ли другие способы решения этой проблемы?

Ответы [ 4 ]

3 голосов
/ 22 марта 2011

В отличие от других ответов, предполагающих, что это нормально, вы должны быть очень осторожны при использовании ThreadStatic или ThreadLocal<T> в приложении ASP.NET.

ASP.NET использует гибкость потоков, что означает, что один и тот же запрос может потенциально обрабатываться несколькими потоками. Чтобы быть в безопасности, вам нужно нарушить инкапсуляцию и хранить ваши элементы в текущем HttpContext, вместо использования ThreadStatic или ThreadLocal<T>:

internal static class DataHolder
{
    internal static ClassName PropertyName
    {
        get { return (ClassName)System.Web.HttpContext.Current.Items["foo"]; }
        set { System.Web.HttpContext.Current.Items["foo"] = value; }
    }
}

К сожалению, эта «особенность» в области потоковых потоков очень плохо документирована. Я вполне уверен, что переключение потоков может происходить только в определенных точках жизненного цикла, а не произвольно, поэтому в зависимости от того, как и где в жизненном цикле используется код, вы могли бы быть в безопасности с ThreadStatic или ThreadLocal<T>.

Я попробую откопать несколько ссылок ...

2 голосов
/ 22 марта 2011

Да.ThreadStatic будет работать для этого.Возможно, вы захотите взглянуть на ThreadLocal , который упрощает работу со статическими переменными потока.

2 голосов
/ 22 марта 2011

Да, [ThreadStatic] должен работать в сценарии, который вы описываете , если , вы можете быть абсолютно уверены, что сторонний код всегда перезванивает вам в том же потоке, который вы вызывали в стороннем коде. Во многих моделях асинхронного обратного вызова это часто не гарантируется. Если обратный вызов строго определен как синхронный обратный вызов, то вы, вероятно, в порядке.

2 голосов
/ 22 марта 2011

ThreadLocal<T> для .NET 4, как упоминалось в этом вопросе:

- это статические классы, общие для разных потоков в C #

Однако, находясь в этой лодкея сам - в итоге я пошел по статическому маршруту.Это работало и было безопасно, потому что это было управляемое состояние.

...