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

时间:2014-07-03 03:54:56

标签: c# multithreading

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

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

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

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

2 个答案:

答案 0 :(得分:1)

界面是否适用于您?

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的更多信息:http://www.ninject.org/learn.html

答案 1 :(得分:0)

我倾向于同意吉姆的观点。

但是,如果您仍然需要这样的类,并且考虑到这两个类提供相同的功能,但其中一个类是ThreadSafe。那么为什么不使用以下?

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

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.
        }
    }
}