gpt4 book ai didi

c# - 带队列的异步/同步并发调用

转载 作者:行者123 更新时间:2023-11-30 18:42:36 25 4
gpt4 key购买 nike

我有一个场景,我正在做一些 Actor-Model 类型的消息队列,我想要一个方法将任务或委托(delegate)插入队列(可能是新的 ConcurrentQueue),等待其他进程处理队列,执行任务然后返回结果,最好不要加锁。可以同步和异步调用该方法。只有一个排队的 Action 可能同时运行

我不知道如何以某种性能方式完成此任务,请帮忙:)

编辑

这是一次尝试,有人发现这种方法有任何问题吗(不包括异常处理)?另外,我可以想象这与简单的锁定相比有相当多的开销,它与使用异步委托(delegate)的实例相比如何?

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


}

最佳答案

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

您可能还想查看 C# 5 async/await 内容。

但请注意:如果您在等待期间不打算做任何有用的事情,您不妨直接在当前线程上运行该代码 - 除非问题是线程绑定(bind)的,例如多路复用器。如果您有兴趣,今天晚些时候(或周末)我打算发布 stackoverflow 用来与 redis 通信的多路复用器,它(至少在同步模式下)确实存在您描述的问题。

作为旁注;如果您可以使用回调(来自其他线程),而不必等待 完成,那么整体效率会更高。但它并不适合所有场景。

关于c# - 带队列的异步/同步并发调用,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/5591833/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com