【问题标题】:How correctly cancel LoadAsync after some timeout超时后如何正确取消 LoadAsync
【发布时间】:2016-01-11 22:08:17
【问题描述】:

考虑我正在使用线程,它在 Windows::Storage::Streams::DataReader (m_reader) 的帮助下从网络套接字 (Windows::Networking::Sockets::StreamSocket) 读取数据流。我需要停止这个线程,它主要在 LoadAsync 中等待。超时后如何正确取消 LoadAsync 方法?

auto t1 = create_task(m_reader->LoadAsync(sizeof(len)));
t1.wait();

我尝试了几种方法,但没有一个能正常工作。或者我不能使用 DataReader,我必须选择其他方法?

【问题讨论】:

  • 关闭套接字即可。不可避免地,这也必须也将结束 LoadAsync()。如果套接字由于某种原因需要生存,请使用 CancelIOAsync()。
  • 我现在这样做了,但它会抛出一些该死的异常:Platform::COMException ^ at memory location 0x1242EB18。 HRESULT:0x800703E3。我想知道是否有更清洁的方法没有这个例外......

标签: multithreading windows-store-apps c++-cx


【解决方案1】:

您的调用t1.wait(); 是一个阻塞调用,如果LoadAsync 调用由于某种原因失败,它将引发异常。在您的情况下,HRESULT 是 ERROR_OPERATION_ABORTED,这几乎是我所期望的(“由于线程退出或应用程序请求,I/O 操作已中止。”)

您可以做的是创建一个任务取消令牌,将其附加到您的任务,然后在需要时触发令牌取消。

来自https://technet.microsoft.com/en-us/office/hh780559

//Class member:
cancellation_token_source m_fileTaskTokenSource;

// Cancel button event handler:
m_fileTaskTokenSource.cancel();

// task chain
auto getFileTask2 =
  create_task(documentsFolder->GetFileAsync(fileName), 
                                 m_fileTaskTokenSource.get_token()); 

注意:在取消令牌上调用 cancel 会导致任务抛出 task_canceled 异常,因此您需要捕获并处理该异常。

【讨论】:

  • 可能是最好的解决方案,但经过一些测试,有时它会抛出 0x800703E3 而不是 task_canceled :-/ 所以不完全可靠
猜你喜欢
  • 1970-01-01
  • 2020-01-07
  • 1970-01-01
  • 2021-05-21
  • 2013-10-18
  • 2023-03-23
  • 1970-01-01
  • 2014-04-09
  • 2012-08-16
相关资源
最近更新 更多