WinRT: DataReader.LoadAsync Exception with StreamSocket TCP

ぐ巨炮叔叔 提交于 2019-12-22 06:49:46

问题


I'm programming a client app on WinRT in C# which connects to several servers by TCP. For the TCP connection I use StreamSocket. The Input and Output Strings are then wrapped in a DataWriter and a DataReader. When I connect to more than one server I get the following exception: "Operation identifier is not valid"

This is the code of the method:

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);

        }
    }

The Stacktrace only shows the reader.LoadAsync(UInt32 count) method as the root of the problem. Each ClientInstance is running in an own task and has it's own DataReader and Stream instance. The "receiveBufferSize" is at 8192 Bytes.

Do you have any idea what the error could be?


回答1:


I think I can answer my question by myself now. The issue was that the LoadAsync method doesn't work so well together with the await/async construct. The method was called by ThreadPool Thread A and then resumed (after await) by ThreadPool Thread B. This constellation threw the Exception. But I can't exactly say why...

With this answer (How to integrate WinRT asynchronous tasks into existing synchronous libraries?) I wrote the LoadAsync method into a synchronous method and now it works because the same thread is calling the method and uses the results of it.

Here is the modified code fragment:

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

Thanks Geoff for bringing me on to the right path with the threads :) I hope I can help someone who also (will) have this issue.




回答2:


It looks to me that the likely cause of the exception is this piece from the documentation:

When a previous call to LoadAsync is not yet complete.

Reading further down:

The LoadAsync method can be called only once on the UI thread. The method cannot be called again until after the LoadCompleted event is raised. The LoadCompleted event is raised whether or not the query succeeds.

Then, combine that with this very thorough answer on why async/await isn't just pure magic sauce:

[...]await does not magically cause a synchronous method to run asynchronously. It does not start up a new thread and run the method on the new thread, for example.

So it would appear that the second call to LoadAsync() is occurring before the first complete; both are made from the same UI thread.



来源:https://stackoverflow.com/questions/16110561/winrt-datareader-loadasync-exception-with-streamsocket-tcp

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!