我有一堆传入的Web请求,我需要将它们序列化并逐个处理。我一次不能处理多个。我目前的解决方案是运行一个工具,可以使用作为共享内存的内存映射文件通过Web API访问该工具。我还需要一个Mutex来允许独占访问共享内存。将使用事件来表示已添加任务。 所以,基本上我们有多个生产者和一个消费者。以下是我的第一个解决方案。有人可以判断是否存在某种竞争条件或任何其他问题:
MemoryMappedFile MMF = MemoryMappedFile.CreateNew("Task_Queue", 5000);
MemoryMappedViewAccessor MMF_Accessor = MMF.CreateViewAccessor();
bool Mutex_Created = false;
Mutex Mutex = new System.Threading.Mutex(false, "Mutex", out Mutex_Created);
if(Mutex_Created==false)
{
// bad error
return;
}
EventWaitHandle EWH = new EventWaitHandle(false, EventResetMode.ManualReset);
Random Rand = new Random();
// Consumer
// work on the Tasks
Task.Factory.StartNew(() =>
{
while (true)
{
// wait until a task has been added
EWH.WaitOne();
// get exclusive access to read in task
Mutex.WaitOne();
byte[] Buffer = ASCIIEncoding.ASCII.GetBytes(new string(' ', 5000));
MMF_Accessor.ReadArray(0, Buffer, 0, Buffer.Length);
int Position = 0;
foreach (var b in Buffer) { if (b == 0) break; Position++; }
string Message = string.Empty;
for (int i = 0; i < Position; ++i)
{
Message += (char)Buffer[i];
}
if(string.IsNullOrEmpty(Message) == false)
{
Console.WriteLine(Message);
}
Mutex.ReleaseMutex();
EWH.Reset();
}
});
// Producer
// via a web request
Task.Factory.StartNew(() =>
{
while (true)
{
if(EWH.WaitOne(0))
{
// consumer must take in the task first
// wait a bit and then try again
Thread.Sleep(100);
break;
}
// wait until we access Shared Memory and claim it when we can
Mutex.WaitOne();
string Request = "Task 1 ";
byte[] Buffer = ASCIIEncoding.ASCII.GetBytes(Request);
Buffer[Buffer.Length - 1] = 0;
MMF_Accessor.WriteArray(0, Buffer, 0, Buffer.Length);
// Signal that a tasks has been added to shared memory
EWH.Set();
// release the mutex so that others can use the shared memory
Mutex.ReleaseMutex();
Thread.Sleep(Rand.Next(10, 1000));
}
});
// Producer
// via a web request
Task.Factory.StartNew(() =>
{
while (true)
{
// wait until we access Shared Memory and claim it when we can
Mutex.WaitOne();
string Request = "Task 2 ";
byte[] Buffer = ASCIIEncoding.ASCII.GetBytes(Request);
Buffer[Buffer.Length - 1] = 0;
MMF_Accessor.WriteArray(0, Buffer, 0, Buffer.Length);
// Signal that a tasks has been added to shared memory
EWH.Set();
// release the mutex so that others can use the shared memory
Mutex.ReleaseMutex();
Random r = new Random();
Thread.Sleep(Rand.Next(10, 1000));
}
});
while (Console.Read() != 'q') ;
请注意,发布的代码仅用于演示目的。