异步套接字读取:启动线程不得退出 - 该怎么办?

发布于 2024-12-02 08:22:25 字数 631 浏览 2 评论 0原文

我有一个异步读取的 NetworkStream(使用 async/await)

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

不幸的是,有时会发生 io 异常:“由于线程退出或应用程序请求,I/O 操作已中止。”

我相信我满足了 Socke.EndReceive 中记录的要求: http://msdn.microsoft .com/en-us/library/w7wtt64b.aspx。其中指出:

当给定线程启动时,所有 I/O 都会被取消 退出。如果线程退出,挂起的异步操作可能会失败 在操作完成之前。

由于异步方法在默认调度程序上运行,因此无法保证此要求。

有办法解决这个问题吗?我需要启动一个专用线程来启动 I/O 吗?

最好的问候,德克

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

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

寄居人 2024-12-09 08:22:25

我在parallelextensions论坛上问了同样的问题:

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

基本上,ThreadPool不会停止任何线程有异步 I/O 挂起。所以只要在ThreadPool上启动socket操作就不会出现这个问题。

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.

花间憩 2024-12-09 08:22:25

我建议使用永不终止的专用 I/O 线程。这就是许多现实世界代码所做的事情。

最好的方法之一是让线程围绕 GetQueuedCompletionStatus。如果需要使 I/O 线程之一执行 I/O 操作,请调用 PostQueuedCompletionStatusQueueUserAPC 到获取 I/O 线程来发布操作。

注意:您必须处理这些操作失败的情况。例如,如果已经排队的 APC 太多,QueueUserAPC 可能会失败。

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.

心的位置 2024-12-09 08:22:25

您可以使用书中最古老的技巧。让你的线程在永无休止的循环中休眠。

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

请注意,我只是从我的脑海中编写了上面的代码。没有在 Visual Studio 中检查它,因为我目前正在 Mac 上工作。

此外,您还需要在需要时编写一些内容来退出线程,但这取决于您的应用程序的流动方式。

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.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文