我创建了一个不安全的类,如果假定为线程安全,则可能导致严重错误。虽然我正在努力使我的类成为线程安全,但我希望将实例限制为仅可由一个线程使用。目前,我的实现方式是在每个暴露点检查当前线程是否与用于构造实例的线程相同。
public class NotThreadSafeClass
{
private readonly int _creatorThreadId;
public NotThreadSafeClass()
{
_creatorThreadId = Thread.CurrentThread.ManagedThreadId;
}
public string ExposedProp
{
get
{
AssertSameThread();
return "My Prop";
}
}
public void ExposedMethod()
{
AssertSameThread();
/* Do stuff */
}
private void AssertSameThread()
{
Throw.If(_creatorThreadId != Thread.CurrentThread.ManagedThreadId,
@"NotThreadSafeClass is not thread safe. Please don't use
the same instance of NotThreadSafeClass in multiple threads.");
}
}
注意:Throw.If定义在http://www.codeducky.org/10-utilities-c-developers-should-know-part-one/中。
这种模式似乎有效,但如果开发人员忘记将此检查添加到任何新的暴露中,则容易出现错误。有没有一种更安全和/或更优雅的方法来确保实例仅被一个线程使用?
ThreadLocal<T>
这样的东西吗? - jdphenixThrow.If
是有害的,因为它会留下一个不明确的异常。而且这也不是正确的复用级别。将ThreadId检查和抛出(一个适当描述的异常)放在一个帮助函数中,那么至少进行检查的负担会更轻,因此更不可能被跳过。 - Ben VoigtThrow.If
来抛出更具体的异常消息。我只是为了简化我的示例而排除了那个帮助函数。我会修改我的示例。 - Steven Wexler