相关疑难解决方法(0)

BlockingCollection(T)性能

在我公司工作了一段时间,我们使用了一个自行开发的ObjectPool<T>实现,它提供对其内容的阻止访问.它非常简单:a Queue<T>,a ,object锁定,以及在AutoResetEvent添加项目时向"借用"线程发出信号.

该类的肉真的是这两种方法:

public T Borrow() {
    lock (_queueLock) {
        if (_queue.Count > 0)
            return _queue.Dequeue();
    }

    _objectAvailableEvent.WaitOne();

    return Borrow();
}

public void Return(T obj) {
    lock (_queueLock) {
        _queue.Enqueue(obj);
    }

    _objectAvailableEvent.Set();
}
Run Code Online (Sandbox Code Playgroud)

我们一直在使用这个和其他一些集合类而不是那些System.Collections.Concurrent因为我们使用的是.NET 3.5而不是4.0.但最近我们发现,由于我们使用无扩展,我们实际上Concurrent提供给我们的命名空间(在System.Threading.dll).

当然,我认为既然BlockingCollection<T>Concurrent命名空间中的核心类之一,它可能会提供比我或我的队友写的更好的性能.

所以我尝试编写一个非常简单的新实现:

public T Borrow() {
    return _blockingCollection.Take();
}

public void Return(T obj) {
    _blockingCollection.Add(obj);
}
Run Code Online (Sandbox Code Playgroud)

令我惊讶的是,根据一些简单的测试(从多个线程借用/返回池几千次),我们的原始实现在性能方面显着优势BlockingCollection<T>.他们似乎都工作正常 ; 只是我们原来的实现似乎要快得多.

我的问题: …

.net collections thread-safety blocking objectpool

22
推荐指数
2
解决办法
1万
查看次数

使用 Task.Yield 在实现生产者/消费者模式时克服 ThreadPool 饥饿

回答问题:Task.Yield - 实际用途? 我建议使用 Task.Yield 允许池线程被其他任务重用。在这样的模式中:

  CancellationTokenSource cts;
  void Start()
  {
        cts = new CancellationTokenSource();

        // run async operation
        var task = Task.Run(() => SomeWork(cts.Token), cts.Token);
        // wait for completion
        // after the completion handle the result/ cancellation/ errors
    }

    async Task<int> SomeWork(CancellationToken cancellationToken)
    {
        int result = 0;

        bool loopAgain = true;
        while (loopAgain)
        {
            // do something ... means a substantial work or a micro batch here - not processing a single byte

            loopAgain = /* check …
Run Code Online (Sandbox Code Playgroud)

c# multithreading threadpool task-parallel-library async-await

5
推荐指数
1
解决办法
1633
查看次数