处理接收到的UDP数据在另一个线程在C# [英] Processing received UDP data in another thread in C#

查看:2125
本文介绍了处理接收到的UDP数据在另一个线程在C#的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有包含在一个单独的线程接收的UDP数据的方法的类。我这样做是为了避免在主应用程序从失速(在Unity3D运行)。

I have a class which contains a method for receiving UDP data in a separate thread. I do this to avoid the main application (which is running in Unity3D) from stalling.

我需要通过被容纳在单独的线程到另一个类的数据, 。它运行原来的线程上,并因此,能够与Unity3D交互

I need to pass the data that is received in the separate thread to another class, which runs on the original thread and, as such, is able to interact with Unity3D.

下面是大致什么UDPReceiver看起来像:

Here is roughly what the UDPReceiver looks like:

public class UDPReciever {

    //...

    public UDPReciever() {
        m_Port = 12345;
        m_Worker = new Thread(new ThreadStart(recvData));
        m_Worker.IsBackground = true;
        m_Worker.Start();
    }

    void recvData() {
        m_UDPClient = new UdpClient(m_Port);
        while (true) {
            try {
                IPEndPoint anyIP = new IPEndPoint(IPAddress.Any, 0);
                byte[] data = (m_UDPClient.Receive(ref anyIP));  

                // TODO: Hand 'data' to NetworkController class (running in the original thread) for processing

            } catch (Exception err) {
                    print(err.ToString());
            }
        }
    }   

}

这是大概什么NetworkController类需要的样子。理想情况下,OnNewData的方法将被称为每当一个新的数据包与作为参数传递的数据接收的时间。

This is roughly what the NetworkController class needs to look like. Ideally the "OnNewData" method would be called every time a new packet is received with the data passed as an argument.

public class NetworkController {

    //...

    void OnNewData(pData) {
        // Process the data in this thread
    }

}

我将如何去实现呢? 。在此先感谢

How would I go about achieving this? Thanks in advance.

推荐答案

下面是它如何做(未测试):

Here is how it could be done (not tested):

public class Dispatcher : MonoBehaviour
{       
    private static readonly BlockingCollection<Action> tasks = new BlockingCollection<Action>();

    public static Dispatcher Instance = null;

    static Dispatcher()
    {
        Instance = new Dispatcher();
    }

    private Dispatcher()
    {
    }

    public void InvokeLater(Action task)
    {
        tasks.Add(task);
    }

    void FixedUpdate()
    {
        if (tasks.Count > 0)
        {
            foreach (Action task in tasks.GetConsumingEnumerable())
            {
                task();
            }
        }
    }
}
...
NetworkController networkControllerInstance;

void recvData()
{
    m_UDPClient = new UdpClient(m_Port);
    while (true)
    {
        try
        {
            IPEndPoint anyIP = new IPEndPoint(IPAddress.Any, 0);
            byte[] data = (m_UDPClient.Receive(ref anyIP));  

            Dispatcher.Instance.InvokeLater(() => networkControllerInstance.OnNewData(data));
        }
        catch (Exception err)
        {
            print(err.ToString());
        }
    }
}



编辑:

一个版本,应该是符合的.Net 3.5

A version that should be compliant with .Net 3.5:

public class Dispatcher : MonoBehaviour
{       
    private static readonly Queue<Action> tasks = new Queue<Action>();

    public static Dispatcher Instance = null;

    static Dispatcher()
    {
        Instance = new Dispatcher();
    }

    private Dispatcher()
    {
    }

    public void InvokeLater(Action task)
    {
        lock (tasks)
        {
            tasks.Enqueue(task);
        }
    }

    void FixedUpdate()
    {
        while (tasks.Count > 0)
        {
            Action task = null;

            lock (tasks)
            {
                if (tasks.Count > 0)
                {
                    task = tasks.Dequeue();
                }
            }

            task();
        }
    }
}



编辑2:

如果你想避免在太长时间冻结的主线:

if you want to avoid freezing the main thread during a too long period:

void FixedUpdate()
{
    if (tasks.Count != 0)
    {
        Action task = null;

        lock (tasks)
        {
            if (tasks.Count != 0)
            {
                task = tasks.Dequeue();
            }
        }

        task();
    }
}

这篇关于处理接收到的UDP数据在另一个线程在C#的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆