Asynchronous socket reading: the initiating thread

2019-04-07 16:06发布

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

3条回答
孤傲高冷的网名
2楼-- · 2019-04-07 16:26

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.

查看更多
Evening l夕情丶
3楼-- · 2019-04-07 16:29

You can use the oldest trick in book. Make your thread sleep in a never ending loop

while(true) {
    Threading.Sleep(TimeSpan.FromSeconds(1); 
}

Note that I have written the above code just from my head. Didn't check it in Visual Studio since I am working on my Mac currently.

Also you will need to write something to exit the thread as well when you need to but that will depend upon how your application is flowing.

查看更多
来,给爷笑一个
4楼-- · 2019-04-07 16:36

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.

查看更多
登录 后发表回答