【发布时间】:2018-08-10 10:36:06
【问题描述】:
这将是非常基本的,但我们遇到了问题并且无法缩小问题范围。希望有人能对此有所了解。
我们有一个简单的静态类
public static class SomeLogger
{
private static ConcurrentQueue<LogObject> queue = new ConcurrentQueue<LogObject>();
private static bool isRunning = false;
public static void Start()
{
if (isRunning) return;
Task.Run(() => Process());
}
public static void Stop()
{
isRunning = false;
}
public static void AddToQueue(LogObject obj)
{
queue.Enqueue(obj);
}
public static void Process()
{
isRunning = true;
using (var p = new SomeClass())
{
while (isRunning)
{
//see if something is in the queue object if yes process it
if(queue.TryDequeue(out LogObject d))
{
//Do some stuff
}
Thread.Sleep(1000);
}
}
}
}
我们在开始时在应用程序事件监听器中调用这个类 - 它调用 SomeLogger.Start - 将 isRunning 设置为 true
到目前为止一切都很好
我们运行 Web 应用程序并多次调用 SomeLogger.Add() 来进行日志记录
但是当我们在本地运行时,即在 iisexpress 上,while 循环会拾取所有添加队列事件并处理它们。
虽然在我们服务器上的 IIS 上执行相同的操作,但只有来自队列的第一个 Add 和 Last Add 消息被选中。??
我们不知道为什么?你们在上面的代码中看到的任何错误..
环境: 简单的 Asp.Net Web API SomeClass 是一个 kafka 生产者
【问题讨论】:
-
什么是
// do some stuff?确定没有抛出异常? -
我没有在代码中看到你重置
isRunning的任何地方。 -
可能不是解决方案,但您可能希望将 if (queue.TryDequeue(...)) 替换为 while (queue.TryDequeue(...))。
-
我没有发现任何问题,并且同意 Patrick 的观点,即问题可能出在处理逻辑上。只是建议使用
Task.Delay(1000).Wait()而不是Thread.Sleep(1000)以保持一致性,我会将Process()方法设为私有。尽管很抱歉,但这与您的问题无关。由于这发生在服务器上而不是本地上,因此可能是连接问题。你能确认AddToQueue每次通话都会被击中吗?感觉代码是好人,所以我的猜测是像帕特里克所说的那样有错误。 -
其他想法:您可能还想用 Task.Delay() 替换 Thread.Sleep() 语句,因为 Thread.Sleep() 会阻塞 Thread,然后不能将其用于其他任何事情.
标签: c# asp.net multithreading