Где хранить данные для текущего вызова WCF? Является ли ThreadStatic безопасным?



в то время как моя служба выполняется, многие классы должны будут получить доступ к пользователю.Текущий (это мой собственный класс пользователя). Могу ли я безопасно хранить _currentUser в [ThreadStatic] переменной? Делает ФОС повторного использования потоков? Если это так, то когда он будет очищать данные ThreadStatic? Если использование ThreadStatic небезопасно, где я должен поместить эти данные? Есть ли место внутри OperationContext.Тока где я могу хранить такие данные?



Edit 12/14/2009: Я могу утверждать, что с помощью ThreadStatic переменная не является безопасным. Потоки WCF находятся в пуле потоков, и переменная ThreadStatic никогда не инициализируется повторно.

583   2  
wcf

2 ответов:

есть блог post что предполагает реализацию IExtension<T>. Вы также можете взглянуть на это обсуждение.

вот предлагаемая реализация:

public class WcfOperationContext : IExtension<OperationContext>
{
    private readonly IDictionary<string, object> items;

    private WcfOperationContext()
    {
        items = new Dictionary<string, object>();
    }

    public IDictionary<string, object> Items
    {
        get { return items; }
    }

    public static WcfOperationContext Current
    {
        get
        {
            WcfOperationContext context = OperationContext.Current.Extensions.Find<WcfOperationContext>();
            if (context == null)
            {
                context = new WcfOperationContext();
                OperationContext.Current.Extensions.Add(context);
            }
            return context;
        }
    }

    public void Attach(OperationContext owner) { }
    public void Detach(OperationContext owner) { }
}

что вы могли бы использовать так:

WcfOperationContext.Current.Items["user"] = _currentUser;
var user = WcfOperationContext.Current.Items["user"] as MyUser;

я обнаружил, что мы пропускаем данные или текущий контекст, когда мы делаем асинхронный вызов с несколькими переключениями потоков. Для обработки такого сценария можно попробовать использовать CallContext. Он должен использоваться в .NET remoting, но он также должен работать в таком сценарии.

установите данные в CallContext:

DataObject data = new DataObject() { RequestId = "1234" };
CallContext.SetData("DataSet", data);

получение общих данных из CallContext:

var data = CallContext.GetData("DataSet") as DataObject;

// Shared data object has to implement ILogicalThreadAffinative

public class DataObject : ILogicalThreadAffinative
{
  public string Message { get; set; }
  public string Status { get; set; }
}

Почему ILogicalThreadAffinative ?

при вызове удаленного метода для объекта в другом домене приложения текущий класс CallContext создает LogicalCallContext, который перемещается вместе с вызовом в удаленное расположение.

только объекты, которые предоставляют ILogicalThreadAffinative интерфейс и хранятся в CallContext распространяются за пределами домена приложения.

Comments

    Ничего не найдено.