Asynchronous Receive Method and Threads |
|
Author |
Message |
mertkan65

|
Posted: .NET Framework Networking and Communication, Asynchronous Receive Method and Threads |
Top |
Hello All,
I have Asynchronous method to read bytes from the network stream. I wrote below code 2 months ago, now when I come back, I wonder why I used "while(true)" for backgroundWorker. Are there any alternative method to use asynchronous read method with backgorundworker Or the method written below is OK
receiveBackgroundWorker.DoWork += new DoWorkEventHandler(Receive);
private void Receive(object sender, DoWorkEventArgs e) { while (true) { dataTransfer.Reset(); clientStream.BeginRead(receiveBuffer = new byte[socket.Available], 0, socket.Available, new AsyncCallback (AsyncReceiveDataCallback), clientStream); dataTransfer.WaitOne(); } }
private void AsyncReceiveDataCallback (IAsyncResult ar) { NetworkStream tempNetworkStream = (NetworkStream)ar.AsyncState; numberOfBytesRead += tempNetworkStream.EndRead(ar); messageQueue.Enqueue(receiveBuffer); if (processBackgroundWorker.IsBusy == false) processBackgroundWorker.RunWorkerAsync(); dataTransfer.Set(); }
.NET Development32
|
|
|
|
 |
mertkan65

|
Posted: .NET Framework Networking and Communication, Asynchronous Receive Method and Threads |
Top |
I tried to run the below code and it seems OK. Is it necessary to use any thread for BeginRead method Is Calling Receive method in asynchronouscallback method correct
public Constructor { Receive(); }
private void Receive() { clientStream.BeginRead(receiveBuffer = new byte[socket.Available], 0, socket.Available, new AsyncCallback (AsyncReceiveDataCallback),
clientStream); }
private void AsyncReceiveDataCallback (IAsyncResult ar) { NetworkStream tempNetworkStream = (NetworkStream)ar.AsyncState; numberOfBytesRead += tempNetworkStream.EndRead(ar); messageQueue.Enqueue(receiveBuffer); Receive(); }
|
|
|
|
 |
mertkan65

|
Posted: .NET Framework Networking and Communication, Asynchronous Receive Method and Threads |
Top |
In the first thread, I used "while(true)" to provide continuity Receive method. When message arrives BeginRead calls the asynchronous callback method and then asynchronous callback method is completed. I need a way to call Receive method again, I used backgroundWorker for this purpose, but it may be unnecessary. The other way is calling Receive method at the end of the Asynchronous callback method, but I am not sure is it correct. I need your opinions...
|
|
|
|
 |
RizwanSharp

|
Posted: .NET Framework Networking and Communication, Asynchronous Receive Method and Threads |
Top |
| I tried to run the below code and it seems OK. Is it necessary to use any thread for BeginRead method Is Calling Receive method in asynchronouscallback method correct
public Constructor { Receive(); }
private void Receive() { clientStream.BeginRead(receiveBuffer = new byte[socket.Available], 0, socket.Available, new AsyncCallback (AsyncReceiveDataCallback), clientStream); }
private void AsyncReceiveDataCallback (IAsyncResult ar) { NetworkStream tempNetworkStream = (NetworkStream)ar.AsyncState; numberOfBytesRead += tempNetworkStream.EndRead(ar); messageQueue.Enqueue(receiveBuffer); Receive(); }
|
|
This approach is 100% OK and Well Formed, You dont need to use Threads or Background Worker with this because this all is already running in Asynchronous mode.
Best Regards,
Rizwan aka RizwanSharp
|
|
|
|
 |
mertkan65

|
Posted: .NET Framework Networking and Communication, Asynchronous Receive Method and Threads |
Top |
Hi Rizwan,
Thank you for your reply:) I tried to run below code, but there is a problem. In messageQueue there are a message and a zero length message then a message again, and it goes on like that. Maybe I should use "try finally" block for callback method. Maybe using step by step method caused such an error.
public Constructor { Receive(); }
private void Receive() { clientStream.BeginRead(receiveBuffer = new byte[socket.Available], 0, socket.Available, new AsyncCallback (AsyncReceiveDataCallback), clientStream); }
private void AsyncReceiveDataCallback (IAsyncResult ar) { NetworkStream tempNetworkStream = (NetworkStream)ar.AsyncState; numberOfBytesRead += tempNetworkStream.EndRead(ar); messageQueue.Enqueue(receiveBuffer); Receive(); }
|
|
|
|
 |
RizwanSharp

|
Posted: .NET Framework Networking and Communication, Asynchronous Receive Method and Threads |
Top |
Yes I put my reply after reading both of them and your direction in the second thread is better callig receive again in the callback will put these functions in recursive mode and you dont need any thread, backgroundworker while(true) for continouty so just give it try.
Yes one thing you missed was try/catch in callback method because some exception can be raised if oher party has been disconnected or network got disconnected etc so exception handling must be there.
Best Regards,
Rizwan aka RizwanSharp
|
|
|
|
 |
mertkan65

|
Posted: .NET Framework Networking and Communication, Asynchronous Receive Method and Threads |
Top |
Thank you Rizwan;)
I want to add something that is useful to above code. Since NetworkStream.Length is not implemented, I decided to use Socket.Avaliable property, but in Asynchronous Callback method, I have to check if it is zero or not before using receiveBuffer. BeginRead method takes arguments before reading data and it may cause corruption. Maybe it will be useful someone else;)
|
|
|
|
 |
RizwanSharp

|
Posted: .NET Framework Networking and Communication, Asynchronous Receive Method and Threads |
Top |
| Thank you Rizwan;)
I want to add something that is useful to above code. Since NetworkStream.Length is not implemented, I decided to use Socket.Avaliable property, but in Asynchronous Callback method, I have to check if it is zero or not before using receiveBuffer. BeginRead method takes arguments before reading data and it may cause corruption. Maybe it will be useful someone else;)
|
|
You welcome dear, NetworkStream.Length will never be implemented because its un seekable stream and may be changing from various sources. But i can't see it use. Why do you need to know the length The simplest thing to do here is to put Try/Catch over int readBytes = stream.EndRead(....);
if(readBytes == 0)
{
// It means disconnected
}
So you simply will never need to know the length.
If you want to read all the data avaialable from the network stream without know how many data it contains You can use a MemoryStream as a temporary buffer.
but it depends how you are dealing with messaging. If you need more idea feel free to write I'll tell you some good ways to deal with such type of situations.
Best Regards,
Rizwan aka RizwanSharp
|
|
|
|
 |
|
|