C# 多线程循环在IIS上不工作
这将是非常基本的,但我们遇到了一个问题,无法缩小问题的范围。希望有人能对此有所启发 我们有一个简单的静态类C# 多线程循环在IIS上不工作,c#,asp.net,multithreading,C#,Asp.net,Multithreading,这将是非常基本的,但我们遇到了一个问题,无法缩小问题的范围。希望有人能对此有所启发 我们有一个简单的静态类 public static class SomeLogger { private static ConcurrentQueue<LogObject> queue = new ConcurrentQueue<LogObject>(); private static bool isRunning = false; public s
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。添加多次日志记录
但是,当我们在本地(即在iisexpress上)运行此程序时,while循环将拾取所有addthequeue事件并对其进行处理
当在我们的服务器上的IIS上执行相同的操作时,只拾取队列中的第一条添加和最后一条添加消息
我们不知道为什么?你们在上面的代码中看到的任何错误
环境:
简单的Asp.NETWebAPI
SomeClass是卡夫卡制作人这里有一个使用TPL数据流库的解决方案
public static class SomeLogger
{
private static readonly BufferBlock<LogObject> _buffer = new BufferBlock<LogObject>();
private static Task _consumer;
private static CancellationTokenSource _cts;
public static void Start()
{
if (_cts != null && !_cts.IsCancellationRequested) return;
_cts = new CancellationTokenSource();
_consumer = ConsumeAsync(_buffer, _cts.Token);
}
public static void Stop()
{
_cts.Cancel();
}
public static void AddToQueue(LogObject log)
{
SendToBuffer(_buffer, log);
}
private static void SendToBuffer(ITargetBlock<LogObject> target, LogObject log)
{
target.Post(log);
}
private static async Task ConsumeAsync(IReceivableSourceBlock<LogObject> source, CancellationToken cancellationToken)
{
while (await source.OutputAvailableAsync(cancellationToken))
{
var log = await source.ReceiveAsync();
// do some stuff
}
}
您甚至可以使用AddToQueue将它们添加到缓冲区,直到调用Start时才会处理它们。什么是//做一些事情?确定没有引发异常?我在代码中没有看到任何重置isRunning的地方。可能不是解决方案,但您可能希望替换if queue.TryDequeue。。。使用while queue.TryDequeue…我没有发现任何错误,我同意Patrick的观点,问题可能出在处理逻辑上。建议使用Task.Delay1000.Wait,而不是Thread.Sleep1000,以确保一致性,我会将进程方法设置为私有。这与你的问题无关,尽管如此,我深表歉意。由于这种情况发生在服务器上而不是本地,所以可能是连接问题。您能否验证AddToQueue是否在每次调用中都被命中?感觉代码是好的,所以我猜是有一个错误,就像Patrick说的或其他什么。其他想法:你可能还想用任务替换Thread.Sleep语句。延迟,作为Thread.Sleep阻塞线程,然后不能用于其他任何事情。这解决了什么问题?