什么是在C#中的线程之间传递数据的快速,内存有效的方法?

Ric*_*h C 6 c# concurrency

我有一个单进程,双线程的应用程序.线程1将收听市场数据Feed并更新数千种股票的最新报价.线程2将以采样频率运行计时器,并获取最新报价的快照以进行处理.实际上,我需要对极快的市场数据源进行下采样.

我对解决方案的第一个猜测是使用BlockingQueue.为此,我需要将计时器功能移动到线程1中,我可以通过每次引用更新时检查时钟并在采样频率上将引号的快照发送到队列来完成.我担心的是队列将占用大量内存,垃圾收集会减慢速度.

我的第二个猜测是让线程1将数据复制到采样频率的锁定成员,线程2可以访问该数据.我担心的是锁会很慢.

我猜想它会使引用原语变得不稳定.由于一个线程只写,一个线程只读,这可能是合适的吗?

是否有最佳实践方法在线程之间为此延迟敏感应用程序传递数据?这不是超高频应用.我可以忍受大约几十毫秒的延迟.

Ric*_*lly 7

如果您只有2个线程访问此资源(即不需要并发读取),那么最简单的(也是最快的一个)就是使用lock关键字:

public class QuoteStore
{
    private readonly List<Quote> _quotes = new List<Quote>();
    private readonly object _mutex = new object();

    public ReadOnlyCollection<Quote> GetQuotes()
    {
      lock (_mutex)
      {
        return _quotes.ToReadOnly();
      }
    }

    public void AddQuote()
    {
      lock (_mutex)
      {
        _quotes.Add(quote);
      }
    }
}
Run Code Online (Sandbox Code Playgroud)

但是,如果需要并发读取,那么这将非常适合ReaderWriterLockSlim类.复制数据时可以获取读锁定,写入数据时可以获取写锁定,例如:

public class QuoteStore : IDisposable
{
    private readonly ReaderWriterLockSlim _mutex = new ReaderWriterLockSlim();
    private readonly List<Quote> _quotes = new List<Quote>();

    public ReadOnlyCollection<Quote> GetQuotes()
    {
      _mutex.EnterReadLock();
      try
      {
        return _quotes.ToReadOnly();
      }
      finally
      {
        _mutex.ExitReadLock();
      }
    }

    public void AddQuote()
    {
      _mutex.EnterWriteLock();
      try
      {
        _quotes.Add(quote);
      }
      finally
      {
        _mutex.ExitWriteLock();
      }
    }

    public void Dispose() 
    {
        _mutex.Dispose();
    }
}
Run Code Online (Sandbox Code Playgroud)

或者,如果您使用.Net 4或更高版本,System.Collections.Concurrent命名空间中有许多可以同时修改的精美集合,您可以使用它们没有任何问题(它们是无锁对象并且通常非常快 - 并且一些性能增强是进来.Net 4.5也是!).