简体   繁体   English

如何在TcpListener线程和主线程之间传输数据?

[英]How can I transfer data between a TcpListener thread and the main thread?

I have a socket-communication thread based on C#. 我有一个基于C#的套接字通信线程。 The buffer in the server is 1024 bytes, now I need a way to transfer the data between the communication thread & the main thread. 服务器中的缓冲区为1024字节,现在我需要一种在通信线程与主线程之间传输数据的方法。 How can I do this? 我怎样才能做到这一点? Do I need to open a new buffer, then copy the data to it? 我需要打开一个新的缓冲区,然后将数据复制到其中吗? Or can I just get the data from the buffer of the client or the server? 还是可以仅从客户端或服务器的缓冲区中获取数据?

private void ServerResponse()
    {
        byte[] buff = new byte[1024];
        string msg;
        int len;
        try
        {
            if (!Stream.CanRead)
            {
                return;
            }

            stopFlag = false;
            while (!stopFlag)
            {
              len = Stream.Read(buff, 0, buff.Length);
                if (len < 1                    
                  {
                    Thread.Sleep(200);
                    continue;
               }
            }
       }
 }

The above is the function that the server uses to get the data from the client. 上面是服务器用来从客户端获取数据的功能。 My question is could I send the data which this function gets to the main thread, or I should set a new buffer outside the definition of the function above and copy the data to it. 我的问题是我可以将该函数获取的数据发送到主线程,还是应该在上面函数的定义之外设置一个新缓冲区,然后将数据复制到该缓冲区。

如果您的主线程通常是所谓的UI线程,那么本讨论将为您提供一些想法: 如何使用后台工作程序更新GUI

You need to write the received message to a buffer accessible by the main thread. 您需要将收到的消息写到主线程可访问的缓冲区中。 You could do this by creating a new buffer (a byte array) for each received message and adding that buffer to a ConcurrentQueue<> , which is good for multithreaded reader/writer scenarios. 您可以通过为每个接收到的消息创建一个新的缓冲区(字节数组)并将该缓冲区添加到ConcurrentQueue <>来实现此目的,这对于多线程读取器/写入器场景很有用。 This way, your listening thread would write received messaged to the queue and your main thread could read messages off the same queue in a thread-safe manner. 这样,您的侦听线程会将接收到的消息写入队列,而您的主线程可以以线程安全的方式从同一队列中读取消息。

Depending on your use case, you might be able to build a more meaningful object (for example a request object) and pass that to the main thread instead of passing bytes. 根据您的用例,您也许可以构建一个更有意义的对象(例如请求对象),并将其传递给主线程,而不是传递字节。

EDIT: based on comment 编辑:基于评论

Assuming you defined a ConcurrentQueue<byte[]> in a public scope: 假设您在公共范围内定义了ConcurrentQueue<byte[]>

public ConcurrentQueue<byte[]> ReceivedMsgs = new ConcurrentQueue<byte[]>();

You could do something like this in the listener thread (right after reading the message bytes into buff ): 您可以在侦听器线程中执行以下操作(将消息字节读入buff ):

var msg = new byte[len];
Buffer.BlockCopy(buff, 0, msg, 0, len);
this.ReceivedMsgs.Enqueue(msg);

Then in the main thread, you can dequeue the messages: 然后在主线程中,可以使消息出队:

byte[] msg;
if (server.ReceivedMsgs.TryDequeue(out msg))
{
    //use msg
}

Depends on how the data needs to be transferred to the main thread. 取决于需要如何将数据传输到主线程。 If in bytes, then just call the following code directly. 如果以字节为单位,则直接调用以下代码。 If not, at first transform data to the presentable form and then call the code: 如果不是,首先将数据转换为可呈现的形式,然后调用代码:

// Place this on the main thread's class initialization.
private static readonly SynchronizationContext _syncContext =
    SynchronizationContext.Current;

// Then your worked thread will be like this:
if (len < 1)                  
{
    Thread.Sleep(200);
    continue;
}
else
{
    _syncContext.Post(o => MainThreadClass.ReceiveData((byte[])buff), buff);
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM