FIFO编程主线程调度程序?

时间:2016-08-30 17:26:27

标签: c# multithreading sockets delegates fifo

首先,我正在使用团结。这使我坚持使用.NET 3.5。我目前正在研究一个使用Socket对象的异步方法(E.G。BeginReceiveBeginAcceptBeginReceiveFrom等)的服务器程序。当服务器从客户端接收数据包时,将在工作线程上接收此数据包。现在我在工作线程上留下了一些数据,我希望主线程使用我指定的函数处理这些数据。我实现了:

using System;
using System.Threading;
using System.Collections;
using System.Collections.Generic;

public class MyDispatcherClass
{
    public delegate void MyDel();
    private readonly Queue<MyDel> commands = new Queue<MyDel>();
    Object lockObj = new object ();

    public void Add(MyDel dc)
    {
        lock (lockObj)
        {
            commands.Enqueue (dc);
        }
    }

    public void Invoke()
    {
        lock (lockObj)
        {
            while (commands.Count > 0)
            {
                commands.Dequeue().Invoke();
            }
        }
    }
}

然后我会这样用它:

// As a global variable:
MyDispatcherClass SomeDispatcher = new MyDispatcherClass ();

//The function that I want to call:
public void MyFunction (byte[] data)
{
    // Do some stuff on the main thread
}

//When I receive a message on a worker thread I do that:
SomeDispatcher.Add (()=> MyFunction (byte[] data)); //Asuume that "data" is the message I received from a client

//Each frame on the main thread I call:
SomeDispatcher.Invoke ();

经过一些研究,我发现lock语句不保证%100 FIFO实现。这不是我想要的,有时这可能导致整个服务器崩溃!我想通过%100保证数据的处理顺序与从客户端接收的顺序相同。我怎么能做到这一点?

1 个答案:

答案 0 :(得分:1)

线程将以他们想要的任何顺序运行,因此您无法强制订单进入队列。但是你可以在队列中输入更多数据,而不仅仅是你最终要处理的数据。

如果您向正在发送的数据添加DateTime(或者甚至只是具有指定顺序的int),您可以在从中提取数据时对其进行排序,(并且可能不会提取少于0.5秒的任何数据)旧的给其他线程留出时间来写他们的数据。)

通常在处理客户端 - 服务器关系时,每个线程代表一个客户端,因此您不必担心这一点,因为命令是线程中的FIFO,(尽管它们可能不是2个不同的客户端发送消息时。)< / p>

您是否关闭并重新打开同一客户端上的套接字?这可能会使它使用不同的线程。如果你需要一个特定的订单并且很快就会发送东西,那么最好让套接字保持打开状态。