S
Shak
Hi all,
I'm trying to write a thread-safe async method to send a message of the form
(type)(contents). My model is as follows:
private void SendMessage(int type, string message)
{
//lets send the messagetype via async
NetworkStream ns = client.GetStream(); //assume client globally
accessible
byte[] bytes = BitConverter.GetBytes(type);
ns.BeginWrite(bytes, 0, bytes.Length, CompleteSend, message); //only
called here in whole application
}
private void CompleteSend(IAsyncResult ar)
{
String message = (string)ar.AsyncState;
NetworkStream ns = client.GetStream();
BinaryWriter writer = new BinaryWriter(ns);
lock (ns)
{
//really need exclusive lock on ns here, since two sends may hit
endwrite at the same time.
ns.EndWrite(ar); // type sent
writer.Write(message); // string sent
writer.Write(DateTime.Now); // extra info sent
}
}
Questions:
1) Is the above the best way to achieve what I want? I could set up a thread
which builds the bytes for the whole message in a memory stream, and then
send that in one go via a blocking ns.Write(), but the above seems more
elegant (and possibly more interesting).
2) Is the lock in a reasonable place? I can't place it after the call to
EndWrite(), since that could allow more than one message type to be sent
before any message content (I'm presuming data actually gets sent when
EndWrite is called. If not, I'm not certain of how you can get concurrency
between multiple async calls). However, I'm afraid of what would happen if
EndWrite was to block, possibly say due to another thread's call to
BeginWrite.
3) Generally, can you have multiple calls to an async Begin* method before
calling the corresponding End* methods?
Thanks!
Shak
I'm trying to write a thread-safe async method to send a message of the form
(type)(contents). My model is as follows:
private void SendMessage(int type, string message)
{
//lets send the messagetype via async
NetworkStream ns = client.GetStream(); //assume client globally
accessible
byte[] bytes = BitConverter.GetBytes(type);
ns.BeginWrite(bytes, 0, bytes.Length, CompleteSend, message); //only
called here in whole application
}
private void CompleteSend(IAsyncResult ar)
{
String message = (string)ar.AsyncState;
NetworkStream ns = client.GetStream();
BinaryWriter writer = new BinaryWriter(ns);
lock (ns)
{
//really need exclusive lock on ns here, since two sends may hit
endwrite at the same time.
ns.EndWrite(ar); // type sent
writer.Write(message); // string sent
writer.Write(DateTime.Now); // extra info sent
}
}
Questions:
1) Is the above the best way to achieve what I want? I could set up a thread
which builds the bytes for the whole message in a memory stream, and then
send that in one go via a blocking ns.Write(), but the above seems more
elegant (and possibly more interesting).
2) Is the lock in a reasonable place? I can't place it after the call to
EndWrite(), since that could allow more than one message type to be sent
before any message content (I'm presuming data actually gets sent when
EndWrite is called. If not, I'm not certain of how you can get concurrency
between multiple async calls). However, I'm afraid of what would happen if
EndWrite was to block, possibly say due to another thread's call to
BeginWrite.
3) Generally, can you have multiple calls to an async Begin* method before
calling the corresponding End* methods?
Thanks!
Shak