使用StreamSocket TCP的WinRT:DataReader.LoadAsyncexception

我正在使用C#在WinRT上编写客户端应用程序,该应用程序通过TCP连接到多个服务器。 对于TCP连接,我使用StreamSocket。 然后将输入和输出字符串包装在DataWriter和DataReader中。 当我连接到多个服务器时,我得到以下exception:“操作标识符无效”

这是方法的代码:

private async void read() { while (true) { uint bytesRead = 0; try { bytesRead = await reader.LoadAsync(receiveBufferSize); if (bytesRead == 0) { OnClientDisconnected(this); return; } byte[] data = new byte[bytesRead]; reader.ReadBytes(data); if (reader.UnconsumedBufferLength > 0) { throw new Exception(); } OnDataRead(this, data); } catch (Exception ex) { if (Error != null) Error(this, ex); } new System.Threading.ManualResetEvent(false).WaitOne(10); } } 

Stacktrace只显示reader.LoadAsync(UInt32 count)方法作为问题的根源。 每个ClientInstance都在自己的任务中运行,并拥有自己的DataReader和Stream实例。 “receiveBufferSize”为8192字节。

你知道错误是什么吗?

我想我现在可以自己回答我的问题了。 问题是LoadAsync方法与await / async构造不能很好地协同工作。 该方法由ThreadPool线程A调用,然后由ThreadPool线程B恢复(等待之后)。这个星座引发了exception。 但我不能确切地说为什么……

有了这个答案( 如何将WinRT异步任务集成到现有的同步库中? )我将LoadAsync方法写入同步方法,现在它可以工作,因为同一个线程正在调用该方法并使用它的结果。

这是修改后的代码片段:

 IAsyncOperation taskLoad = reader.LoadAsync(receiveBufferSize); taskload.AsTask().Wait(); bytesRead = taskLoad.GetResults(); 

感谢Geoff让我带着线程走上了正确的道路:)我希望我能帮助那些也会(将)解决这个问题的人。

在我看来,exception的可能原因是文档中的这一部分:

先前对LoadAsync的调用尚未完成时。

进一步阅读:

LoadAsync方法只能在UI线程上调用一次。 在引发LoadCompleted事件之前,不能再次调用该方法。 无论查询是否成功,都会引发LoadCompleted事件。

然后,结合这个非常彻底的答案 ,为什么async / await不仅仅是纯魔术酱:

[…] await不会神奇地导致同步方法异步运行。 例如,它不会启动新线程并在新线程上运行该方法。

因此看起来第二次调用LoadAsync()发生在第一次完成之前; 两者都是由相同的UI线程构成的。