How do I cancel an asynchronous operation?

J

Jacob

I'm writing a class that communicates with a server using the TcpClient
class. Most of the methods I've written are intended to be used
synchronously and will block until they are completed. But these calls will
be made very seldom and between operations I would like to put the client
into a "listening mode" that will listen for other server messages. When
the client is ready to send/receive data again, take it back out of
listening mode and again begin synchronous operations. It's quite easy to
set up a BeginRead on the stream I created and have its callback process any
messages received from the server. But when I want to STOP listening and
start synchronous operations again I need to be able to cancel this. I
think the easiest way would be if I could just cancel the thread that I
started the BeginRead operation on. I'm sure there is a way to use the
IAsyncResult or it's WaitHandle to cancel the thread, but threading is not
my strongpoint and a solution is alluding me right now. Any assistance
would be appreciated. Here's the skeleton of what I'm going for.

private IAsyncResult ar;

private void Listen()
{
listenBuffer = new byte[1024];
ar = stream.BeginRead(listenBuffer, 0, listenBuffer.Length, new
AsyncCallback(ListenMessage), this);
}


private void ListenMessage(IAsyncResult ar)
{
// ..... interpret received message.
}


private void StopListen()
{
// ?????? ar...
}




Any help is appreciated,
Jacob
 
D

Dmitriy Lapshin [C# / .NET MVP]

Jacob,
started the BeginRead operation on. I'm sure there is a way to use the
IAsyncResult or it's WaitHandle to cancel the thread, but threading is not
my strongpoint and a solution is alluding me right now. Any assistance
would be appreciated. Here's the skeleton of what I'm going for.

Unfortunately, cancelling the async. operations is not supported by the .NET
framework. I have recently had to write my own replacement since
cancellation was a must.
 
J

Jacob

Well, that answers my question. Thanks for your help.

Jacob


Dmitriy Lapshin said:
Jacob,
started the BeginRead operation on. I'm sure there is a way to use the
IAsyncResult or it's WaitHandle to cancel the thread, but threading is not
my strongpoint and a solution is alluding me right now. Any assistance
would be appreciated. Here's the skeleton of what I'm going for.

Unfortunately, cancelling the async. operations is not supported by the ..NET
framework. I have recently had to write my own replacement since
cancellation was a must.

--
Dmitriy Lapshin [C# / .NET MVP]
X-Unity Test Studio
http://x-unity.miik.com.ua/teststudio.aspx
Bring the power of unit testing to VS .NET IDE
 
C

Chris Morse

Jacob,


Unfortunately, cancelling the async. operations is not supported by the .NET
framework. I have recently had to write my own replacement since
cancellation was a must.

I am just researching this same problem. In my case, it's a server
socket that calls "BeginAccept()". The MSDN doc sample "Using an
Asynchronous Server Socket" shows this code:

try {
listener.Bind(localEP);
s.Listen(10); // <-- typo in MSDN docs!

while (true) {
allDone.Reset();

Console.WriteLine("Waiting for a connection...");
listener.BeginAccept(
new AsyncCallback(SocketListener.acceptCallback),
listener );

allDone.WaitOne();
}
} catch (Exception e) {
Console.WriteLine(e.ToString());
}

An infinite loop of BeginAccept() calls is NOT what I would want in my
own server. As I have been trying to figure out how to cancel a
"pending" BeginAccept() call, I am finding out now that it can't be
done.

It's not too big a problem for me, as my own version has a way out of
the loop and closes the server socket. Either the server socket
closing OR the thread ending (which happens after the close) causes
the acceptCallback to be called ONCE the first time, and if I continue
hitting my server start and stop buttons, the acceptCallback will be
called TWICE everytime after that. Strange behaviour.

So I have been trying to figure out how to cancel the pending
BeginAccept() call. And now it seems it can't be done!

// CHRIS
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Top