C # Как убедиться, что пользователь предоставляет потокобезопасный объект для функции - PullRequest
1 голос
/ 23 июля 2011

У меня есть класс Server, который после принятия TcpClient вызывает событие, основной задачей которого является получение определенного пользователем объекта для передачи в поток, принадлежащий TcpClient. например,

public class MyData : UserData {}
public GetUserDataEventArg : CancelEventArg { UserData Data { get; set; } }
public class Server { public event EventHandler<GetUserDataEventArg> GetUserData = null; }
// intended usage, each thread has its own data.
public void GetUserDataEventHandler1(object sender, GetUserDataEventArg e) { e.Data = new MyData(); } 
// dangerous usage, shared member data may not have thread safety implemented.
public void GetUserDataEventHandler2(object sender, GetUserDataEventArg e) { e.Data = m_myData; } 

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

Ответы [ 2 ]

3 голосов
/ 23 июля 2011

Вы не можете написать код, который берет объект, который может проверить этот объект, чтобы выяснить, является ли он потокобезопасным.

Таким образом, вы должны выбрать между:

  1. Предположим, что является поточно-ориентированным, накладывает бремя на провайдера этого объекта, т.е. звонящий
  2. Предположим, что не является поточно-ориентированным, возлагает на вас бремя, чтобы обрабатывать этот объект поточно-ориентированным образом

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

2 голосов
/ 23 июля 2011

Попробуйте это:

public class MyData
{
    private int _originatingThreadId;

    public MyData()
    {
        _originatingThreadId = Thread.CurrentThread.ManagedThreadId;
    }

    public void ThreadUnsafeMethod()
    {
        if(Thread.CurrentThread.ManagedThreadId != _originatingThreadId)
            throw new Exception("This method should only be called from the thread on which the original object was created");
    }
}

Имейте в виду, что это не будет работать, если вы используете это из контекста ASP.Net, так как запросы могут использовать то, что называется «гибкость потока», что означает, что запрос может быть передан другому потоку в течение его жизненного цикла .

...