C# 是否可以创建一个既可以是线程安全的又可以是非线程安全的类?

C# 是否可以创建一个既可以是线程安全的又可以是非线程安全的类?,c#,multithreading,C#,Multithreading,我有一个我想在不同场景中使用的类,其中一个在单线程环境中,另一个在多线程环境中。我想知道是否通过泛型或其他范例,我可以创建一个实现这两种行为的类,而不必创建两个单独的类,或者传递在每个方法中检查的标志 2个类,1个线程安全,1个非线程安全。我可以优雅地组合成一个吗 public class Position { public void Adjust(Trade newfill) { lock(locker) {

我有一个我想在不同场景中使用的类,其中一个在单线程环境中,另一个在多线程环境中。我想知道是否通过泛型或其他范例,我可以创建一个实现这两种行为的类,而不必创建两个单独的类,或者传递在每个方法中检查的标志

2个类,1个线程安全,1个非线程安全。我可以优雅地组合成一个吗

public class Position
{
      public void Adjust(Trade newfill)
      {
         lock(locker)
         {
            ....
         }
      }
}

public class PositionNTS
{
      public void Adjust(Trade newfill)
      {
           ...
      }
 }

我倾向于同意吉姆的观点

但是,如果您仍然需要这样一个类,并且考虑到这两个类都提供相同的功能,但是其中一个类是线程安全的。那么为什么不使用下面的方法呢

根据要使用这些类的线程环境创建/使用实例

public class Trade
{
}

public class PositionNTS
{
    public virtual void Adjust(Trade newfill)
    {

    }
}

public class Position : PositionNTS
{
    private readonly object locker = new object();

    public override void Adjust(Trade newfill)
    {
        lock (locker)
        {
            base.Adjust(newfill);
        }
    }
}
更新

这是您可以使用的另一种方法,决策仍然保持在更高的级别,以指示要传递哪个泛型参数

public class Trade
{

}

public interface IRunner
{
    void Adjust(Trade newfill);
}

public class Executor
{
    private IRunner runner;
    public void Adjust<T>(Trade newFill) where T : class, IRunner, new()
    {
        if(runner == null || (runner as T) == null)
        {
            runner = new T();
        }
        runner.Adjust(newFill);
    }
}

public class Runner : IRunner
{
    public void Adjust(Trade newfill)
    {
        //your logic here.
    }
}

public class SynchronizedRunner : IRunner
{
    private readonly object syncLockObject = new object();
    public void Adjust(Trade newfill)
    {
        lock (syncLockObject)
        {
            //your logic here.
        }
    }
}
公共级贸易
{
}
公共接口IRunner
{
无效调整(交易新填充);
}
公共类执行者
{
私人跑步者;
公共无效调整(交易新填充),其中T:class,IRunner,new()
{
如果(转轮==null | |(转轮为T)==null)
{
runner=新的T();
}
流道。调整(新填充);
}
}
公开课跑者:IRunner
{
公共无效调整(交易新填充)
{
//你的逻辑在这里。
}
}
公共类同步运行程序:IRunner
{
私有只读对象syncLockObject=新对象();
公共无效调整(交易新填充)
{
锁定(syncLockObject)
{
//你的逻辑在这里。
}
}
}

界面是否适合您的应用程序

public interface IPosition
{
    void Adjust(Trade newfill)
}

public class PositionNTS : IPosition
{
    public void Adjust(Trade newfill)
    {
         ...
    }
}

public class Position : IPosition
{
    private readonly object locker = new object();

    public void Adjust(Trade newfill)
    {
        lock (locker)
        {
            ...
        }
    }
}
您询问了泛型,因此这可能是您不想使用的部分(我假设您的代码中有特定部分希望使用线程安全部分,而其他部分希望使用非线程安全部分,而不是简单地在两者之间交换)。如果您所说的环境是指生产环境与本地环境(对于非线程安全版本可能没问题),那么您可以使用IoC在接口实例化为什么之间切换。有关更多信息,请参阅链接。
有关IoC的更多信息:

无争用锁可能需要20纳秒。如果此代码对性能不太敏感,那么即使在单线程环境中,也只需使用具有锁的代码。如果确实需要区别,请创建
接口
,并在需要它们的地方插入任何一个类。您的工厂应该决定此处需要什么类型的处理,然后提供适当的实现。虚拟调度的额外成本(糟糕的静态预测)可能远远超过输入无争用锁的成本。根据上下文,这可能有风险(在锁内使用方法调用很容易给您带来糟糕的竞争条件,当然更糟糕的是事件——但谁知道呢,调整后可能会触发事件?)我认为提问者应该意识到这一点。这就是我提到的按照线程环境使用实例的上下文。我不想这样做,因为我必须对这两个类都做任何更改。我认为最安全的做法是保持锁定不变。我们有一个单线程模拟器和一个多线程o共享该类的optimizer。该优化器速度非常慢,我们发现许多性能问题可以解决。我想知道是否可以使用该类来做一些事情,但这可能是我们遇到的问题中最不令人讨厌的。感谢您的帮助!另一种更新的方法,是的,很遗憾,类无法隐式决定“使用或删除”不要用锁。