【问题标题】:Azure QueueClient MaxConcurrentCalls Not WorkingAzure QueueClient MaxConcurrentCalls 不起作用
【发布时间】:2016-09-16 11:34:20
【问题描述】:

我的任务是提高处理来自队列的消息的工作角色的性能。

它使用queueclient.OnMessage 模型,MaxConcurrentCalls 设置为 1。

在处理过程中,thread.sleep 会持续 5 分钟,这会影响整体性能,即如果队列中有 10 条消息,则至少需要 45 分钟才能处理第 10 条消息

我想如果我将 MaxConcurrentCalls 更改为 5,那么它应该并行处理 5 条消息并将等待时间减少 25 分钟,但这不起作用:(

我还尝试将 OnMessageAsync 与 MaxConcurrentCalls 一起使用,但没有运气。下面是我试过的sn-p,

.OnMessageAsync( async (brokeredMessage) =>
{                
    bool shouldAbandon = false;
    try
    {
        logger.Debug("Rcvd:" + brokeredMessage.SequenceNumber);
        SomeTask(brokeredMessage);
        await brokeredMessage.CompleteAsync();
    }
    catch (Exception ex)
    {
        logger.Error(String.Format("An Error occured {0}", ex.ToString()));
        shouldAbandon = true;
    }
    if (shouldAbandon)
    {
        await brokeredMessage.AbandonAsync();
    }   
}, new OnMessageOptions { AutoComplete = false, MaxConcurrentCalls = 10 });

private void SomeTask(BrokeredMessage bm)
{            
    logger.Debug("id: " + bm.MessageId + "on thread: " + Thread.CurrentThread.ManagedThreadId);
    Thread.Sleep(30 * 1000);
    logger.Debug("seq: " + bm.SequenceNumber);
    logger.Debug("body: " + bm.GetBody<string>());
}

我能想到的最后一个选项是在 OnMessage 事件上启动一个新任务。我需要处理几件事(确保从集合/主线程中删除已完成的任务并从 BrokeredMessage 传递一个对象,因为 BrokeredMessage 已被释放,因此我无法在任务线程上使用)并且我有理智也对其进行了测试,但我不相信这是最好的解决方案。

【问题讨论】:

  • 忘了提到任务方法的最大缺点,如果处理失败,我们将丢失消息,而默认情况下消息可能会在队列中。
  • 睡眠的目的是什么?模拟一个漫长的过程?你有没有尝试让你的 SomeTask 函数异步?
  • 是的@Thomas,睡眠模拟了长时间运行的过程。我尝试从 SomeTask 方法返回 Task 以使其异步,但这不起作用,因为代码仍在使用 Sleep 但后来我在 C# 多线程 (stackoverflow.com/questions/14177891/…) 上遇到另一个线程,我意识到我需要使用 Task.Delay这正如我预期的那样工作

标签: multithreading azure azureservicebus azure-servicebus-queues


【解决方案1】:

SomeTask 实现替换为以下内容:

async Task SomeTask(BrokeredMessage bm)
{
     logger.Debug("id: " + bm.MessageId + "on thread: " + Thread.CurrentThread.ManagedThreadId);
     await Task.Delay(30 * 1000).ConfigureAwait(false);
     logger.Debug("seq: " + bm.SequenceNumber);
     logger.Debug("body: " + bm.GetBody<string>());
}

Thread.Sleepasync 在同一个线程上混合时(在您的情况下),它会导致线程“停止”所有任务。由于没有 UI 工作,因此更喜欢在异步操作上使用 .ConfigureAwait(false) 以允许调度程序管理要在哪个线程上执行。

【讨论】:

  • 感谢@Sean,很抱歉因为我不在,所以回复晚了,但这正是我去度假前所做的,而且效果很好。关键是使用 Task.Delay 而不是 Thread.Sleep 我从stackoverflow.com/questions/14177891/… 意识到。
猜你喜欢
  • 1970-01-01
  • 2022-10-01
  • 2017-04-25
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-06-03
  • 2015-10-19
  • 2020-09-21
相关资源
最近更新 更多