首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >具有队列的异步/同步并发调用

具有队列的异步/同步并发调用
EN

Stack Overflow用户
提问于 2011-04-08 07:23:49
回答 1查看 1.6K关注 0票数 3

我有一个场景,在这个场景中,我正在执行一些Actor-Model类型的消息等号,其中我希望有一个方法将一个任务或委托插入到一个队列(可能是新的ConcurrentQueue)中,等待其他进程处理队列,执行任务,然后返回结果,最好没有锁定。可以同步和异步地调用该方法。只有一个排队的操作可以同时运行。

我无法思考如何以一种有点表现力的方式来完成这一任务,请帮助:)

编辑

这里有一个尝试,有人发现这种方法有任何问题(排除异常处理)?而且,我可以想象,与简单的锁定相比,这有相当大的开销,并且与例如使用异步委托相比,它是如何比较的?

代码语言:javascript
复制
  public partial class Form1 : Form
  {
    private BlockingCollection<Task<int>> blockingCollection = new BlockingCollection<Task<int>>(new ConcurrentQueue<Task<int>>());
    private int i = 0;
    public Form1() {
      InitializeComponent();

      Task.Factory.StartNew(() =>
      {
          foreach (var task in blockingCollection.GetConsumingEnumerable()) {
            task.Start();
            task.Wait();        
          }
      });
    }


    public int Queue() {
      var task = new Task<int>(new Func<int>(DoSomething));
      this.blockingCollection.Add(task);
      task.Wait();
      return task.Result;
    }

    public int DoSomething() {
      return Interlocked.Increment(ref this.i);
    }

    private void button1_Click(object sender, EventArgs e) {
      Task.Factory.StartNew(() => Console.Write(this.Queue()));
    }


  }
EN

回答 1

Stack Overflow用户

发布于 2011-04-08 07:58:44

TPL应该为您做这件事--只需在您的Task<T>上调用Task<T>--但是,在不阻塞的情况下,无法做到这一点;根据定义,在您的场景中,这正是您想要做的。阻塞可以通过lock实现,但也有其他方法-- TPL隐藏了这一点。就个人而言,在类似的场景中,我使用一个自定义队列和一个可以用来锁定的小型对象池(从未暴露在包装器之外)来执行此操作。

您可能还需要查看C# 5异步/等待的内容。

但是请注意:如果您在等待时没有做任何有用的事情,那么最好在当前线程上直接运行该代码--除非问题是线程绑定的,例如多路复用器。如果您感兴趣,今天晚些时候(或周末),我打算发布堆栈溢出用于与redis对话的复用器,它(至少在同步模式下)有您所描述的问题。

顺便提一句,如果您可以使用回调(来自另一个线程),而不必等待完成,那么总体上来说,这是更有效的。但并不是每一种情况都适合。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/5591833

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档