使用内存映射文件序列化任务

时间:2015-09-05 23:40:30

标签: c# ipc shared-memory

我有一堆传入的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') ;

请注意,发布的代码仅用于演示目的。

0 个答案:

没有答案