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

标签 c# concurrency

我有一个单进程、双线程的应用程序。线程 1 将收听市场数据提要并更新数千只股票的最新报价。线程 2 将以采样频率运行计时器,并拍摄最新报价​​的快照以供处理。实际上,我需要对极快的市场数据馈送进行下采样。<​​/p>

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

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

我第三次猜测它会使引用原语变得易变。既然一个线程只写一个线程只读,也许这样合适?

对于这个对延迟敏感的应用程序,是否有最佳实践方法来在线程之间传递数据?这不是超高频应用。我可以容忍数十毫秒的延迟。

最佳答案

如果您只有 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);
      }
    }
}

如果需要并发读取,这将非常适合 the ReaderWriterLockSlim class .复制数据时获取读锁,写数据时获取写锁eg:

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();
    }
}

或者,如果您使用的是 .Net 4 或更高版本,the System.Collections.Concurrent namespace 中有许多精彩的并发可修改集合您可能可以毫无问题地使用它(它们是无锁对象,通常非常快 - 和 some performance enhancements are coming in .Net 4.5 too !)。

关于c# - 在 C# 中的线程之间传递数据的快速、内存高效的方法是什么?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/8804599/

相关文章:

c# - 在 MemoryCache 调用上停止重入

c# - 如何在csharp中使用泛型类型继承

c# - 登录不起作用

c# - C#Google Cloud文字转语音-Wavenet问题

c# - 如何使用 SQL Server 数据库部署 C#/WPF 应用程序

java - volatile 变量和其他变量

javascript - 将 javascript 值传递给 C# 值

java - 使用 FutureTask 比 Callable 有什么优势?

java - 使用 future.cancel() 终止底层线程以重新使用该线程

ruby - 学习Ruby线程-线程完成时触发事件