Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Asynchronous socket reading: the initiating thread must not be exited - what to do?

I have a NetworkStream which I read asynchronously (using async/await)

await Task<int>.Factory.FromAsync((cb, state) => stream.BeginRead(buffer, offset, readLen - offset), stream.EndRead, null);

Unfortunatly, an io exception sometimes occurs: "The I/O operation has been aborted because of either a thread exit or an application request."

I believe I hit a requirement documented in Socke.EndReceive: http://msdn.microsoft.com/en-us/library/w7wtt64b.aspx . Which states:

All I/O initiated by a given thread is canceled when that thread exits. A pending asynchronous operation can fail if the thread exits before the operation completes.

Because the async method runs on the default scheduler, this requirement cannot be assured.

Is there a way around this? Do I need to start a dedicated Thread to initiate I/O?

best regards, Dirk

like image 909
Dirk Bonné Avatar asked Aug 30 '11 11:08

Dirk Bonné


2 Answers

I have asked the same question on the parallelextensions forum:

http://social.msdn.microsoft.com/Forums/en-US/parallelextensions/thread/d116f7b0-c8ee-4ce4-a9b8-4c38120e45a4

Basically, the ThreadPool will not stop any threads that has asynchronous I/O pending. So as long as one starts the socket operation on the ThreadPool this problem should not occur.

like image 82
Dirk Bonné Avatar answered Nov 11 '22 21:11

Dirk Bonné


I would recommend using dedicated I/O threads that never terminate. That is what a lot of real-world code does.

One of the best ways to do it is to have the threads loop around GetQueuedCompletionStatus. If you need to make one of the I/O threads perform an I/O operation, call either PostQueuedCompletionStatus or QueueUserAPC to get the I/O thread to post the operation.

CAUTION: You must handle the case where these operations fail. QueueUserAPC, for example, can fail if too many APCs are already queued.

like image 29
David Schwartz Avatar answered Nov 11 '22 20:11

David Schwartz