如何防止 class 在另一个线程中被使用

How to prevent a class from being used in another thread

我有一个 class 我只想在一个线程中使用。如果我在一个线程中创建一个 class 的对象并在另一个线程中使用它,将会导致很多问题。目前,我这样解决这个问题: 我有上下文 class,我只想在一个线程中使用它:

public class Context
{
    public Thread CreatedThread { get; }

    public Context()
    {
        CreatedThread = Thread.CurrentThread;
    }

    public void AssertThread()
    {
        if (CreatedThread != Thread.CurrentThread)
        {
            throw new InvalidOperationException("Use only one thread!");
        }
    }

    //Lot of properties and methods here
}

这里是 Context class 在 Student class 中的用法:

public class Student
{
    Context context;
    public Context Context
    {
        get
        {
            if (context == null)
                context = new Context();
            context.AssertThread();
            return context;
        }
    }
}

当我在不同的线程中使用上下文时,它会抛出一个错误:

var student = new Student();
var context = student.Context;

Task.Run(() =>
{
    var context = student.Context;//InvalidOperationException
});

但是这个解决方案并不可靠。例如,当我有另一个使用上下文的 class 时,我需要在获取上下文 属性 时执行 AssertThread。或者当我在一个新变量中获取上下文并在不同的线程中使用它时,我的异常将不会被抛出。那么,是否有任何解决方案可以强制 class 仅在一个线程中使用?

据我所知,C# 语言和标准 .NET API 都没有提供一种方法来自动嵌入 AssertThread() 检查每个 public 方法的开头和 属性 class。如果你不喜欢手动添加这个检查的想法,而且你很认真,你可能想搜索一些可以在编译时自动为你添加这个检查的 tool/add-on,比如 PostSharp, Fody or alternatives.