为什么Thread.Sleep()在以下上下文中使用以及如何避免它?

时间:2017-11-21 05:12:50

标签: c# multithreading

我正在通过Http发送消息的方法。

        private static void HTTPProcessQueue()
        {
            while (true)
            {
                try
                {
                    Thread.Sleep(10000);
                    Utils.LogDebug("Msg Queue Check");
                    while (msgQueue.Count > 0)
                    {
                        QueueItem queueItem;
                        lock (msgQueue)
                        {
                            queueItem = msgQueue.Dequeue();
                        }
                        if (queueItem != null)
                            if(!HTTPTransmitEmailItem(queueItem.username, queueItem.filename))
                                Thread.Sleep(5000);
                    }
                }
                catch (Exception ex)
                {
                }
            }
        }
  1. 在上面的代码中,为什么第7行和第18行使用了Thread.Sleep(10000)Thread.Sleep(5000)
  2. 另外,为什么第3行有while(true)

2 个答案:

答案 0 :(得分:2)

根据您的要求,这是一种更好的方法:

private static System.Collections.Concurrent.BlockingCollection<MsgType> msgQueue = new System.Collections.Concurrent.BlockingCollection<MsgType>();

private static void AddQueueItems() // simulate adding items to the queue
{
    msgQueue.Add(new MsgType());
    msgQueue.Add(new MsgType());
    msgQueue.Add(new MsgType());
    msgQueue.Add(new MsgType());

    // when adding is done, or the program is shutting down
    msgQueue.CompleteAdding();
}

private static void HTTPProcessQueue()
{
    foreach (var queueItem in msgQueue.GetConsumingEnumerable())
    {
        if (queueItem != null)
        {
            if (!HTTPTransmitEmailItem(queueItem.username, queueItem.filename))
            {
                Thread.Sleep(5000);
            }
        }
    }
}

我建议在HTTPTransmitEmailItem中使用async / await模式,然后您可以使用等待Task.Delay(...)而不是Thread.Sleep(...)。我还没有在此代码中包含任何错误检查。

这看起来更像是:

private static async Task HTTPProcessQueue()
{
    foreach (var queueItem in msgQueue.GetConsumingEnumerable())
    {
        if (queueItem != null)
        {
            if (!(await HTTPTransmitEmailItemAsync(queueItem.username, queueItem.filename)))
            {
                await Task.Delay(5000);
            }
        }
    }
}

但你必须制作一个HttpTransmitEmailItemAsync方法。另请注意,GetConsumingEnumerable(...)方法有一个带有CancellationToken的重载,因此您可以使用它来更好地控制何时结束队列进程。您可以了解async / await here

答案 1 :(得分:0)

  1. 在第7行使用Thread.Sleep(10000)让系统暂停/等待10秒,然后启动函数Utils.LogDebug(&#34; Msg Queue Check&#34;);使用消息&#34; Msg Queue Check&#34;记录调试信息。我相信在循环结束时添加Thread.Sleep(5000)以创建延迟或等待5秒后再处理下一个循环。

  2. while(true)通常用于无限循环。这个循环中的所有方法都将在无限时间内循环运行。