0

I have a socket-communication thread based on 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. 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.

Niall C.
  • 10,878
  • 7
  • 69
  • 61
psyche
  • 193
  • 1
  • 1
  • 7
  • Asynchronous Methods made easy with .NET 4.5: http://www.codeproject.com/Articles/274062/Improved-Multi-Threading-Support-in-Net-4-5 – astro boy Jun 13 '12 at 06:25

3 Answers3

0

If your main thread is what typically is called the UI thread, this discussion will give you some ideas: how to update GUI with background worker

Community
  • 1
  • 1
Mare Infinitus
  • 8,024
  • 8
  • 64
  • 113
0

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. 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:

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):

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
}
Eren Ersönmez
  • 38,383
  • 7
  • 71
  • 92
  • as you said, the new buffer is diffrent from the buffer that server already had, I should creat a readble buffer and a writtenable buffer accessible by the main thread, and put all these buffer(include the buffer that server already had) into a ConsurrentQueue. Am I right? – psyche Jun 13 '12 at 08:35
0

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);
}
AgentFire
  • 8,944
  • 8
  • 43
  • 90