1

我的应用程序将用户凭据发送到服务器,如果他们是正确的,服务器会发送一个数据包,告诉客户端他们的凭据是错误的还是正确的。经过几次虚拟测试后,我的客户端由于这行代码而崩溃;

            var count = await reader.LoadAsync(512);

调试显示计数为0,

但在崩溃之前,我能够向服务器发送七 (7) 个虚拟请求。客户能够阅读七 (7) 份回复。

    private async void loginButtonEvent(object sender, RoutedEventArgs e)
    {
        //disable the button so the user can't spam the login button and flood packets 
        loginButton.IsEnabled = false;

        //if the user is connected to the server, then allow
        if(connected)
        {
            //get the stream
            DataWriter writer = new DataWriter(clientSocket.OutputStream);

            //custom class (like a packet IO, messafe frame/ framing
            MessageData md = new MessageData();
            md.MyUser = new User(usernameTextBox.Text, passwordTextBox.Text);
            md.MyType = MessageData.mType.LOGINREQUEST;
            //Serialize it into a string, thank you newton.Json
            string output = JsonConvert.SerializeObject(md);
            //write to the server
            writer.WriteString(output);
            //dedicate and push
            await writer.StoreAsync();
            //flush like you flush a toilet so it doesn't get clogged in the pipeline
            await writer.FlushAsync();
            //detatch the stream, not sure why?
            writer.DetachStream();

            //get the input stream
            DataReader reader = new DataReader(clientSocket.InputStream);
            //create string to hold the data
            string receivedData;
            //dynamically process the data
            reader.InputStreamOptions = InputStreamOptions.Partial;
            //store the bytes in count? why do we pass 512? What if I send a picture to the server and it is 1mb?
            var count = await reader.LoadAsync(512);
            //covert the byte to a string
            receivedData = reader.ReadString(count);
            //construct the md object into what the server sent
            md = JsonConvert.DeserializeObject<MessageData>(receivedData);
            switch (md.MyType)
            {
                case MessageData.mType.LOGINFAILED:
                    messageBox("Username or Password is wrong");
                    //Todo://
                    break;
                case MessageData.mType.LOGINSUCCESS:
                    messageBox("Logged");
                    //TODO: Go to login screen
                    break;
            }

            await System.Threading.Tasks.Task.Delay(TimeSpan.FromSeconds(1));


        }
        loginButton.IsEnabled = true;


    }

我再次对此进行了测试,这次我能够向服务器发送十二 (12) 个数据包,并接收到客户端能够解释的十二 (12) 个数据包。

再次,错误在于

            var count = await reader.LoadAsync(512);

MobileApp.exe 中出现“System.ObjectDisposedException”类型的异常,但未在用户代码中处理

用户代码未处理 Object Disposable Exception。

4

2 回答 2

1

You're navigating into tricky waters when you call LoadAsync from within an async method. The LoadAsync method should only be called once from the UI thread. The method cannot be called again until after the LoadCompleted event is raised. Most likely your calling it a second time before the previous request is complete.

Try switching out the offending await line to something like this:

IAsyncOperation<int> asyncOp= reader.LoadAsync(512);
asyncOp.AsTask().Wait();
var count = asyncOp.GetResults();

If you want a really long answer that goes into more detail, please see this answer: https://stackoverflow.com/a/9898995/3299157

于 2016-02-17T14:38:28.327 回答
1
             //start a new task!
            Task t = new Task(ListenForMessage);
            //if the currrent task is not completed, then return
            //this means it wont calll var count = await reader.LoadAsync(512); I.E the devil
            if (!t.IsCompleted)
                return;

            //else if the task is completed, then run it!
            t.RunSynchronously();

Thanks to Ageonix, I was able to come to this conclusion, due to his answer which caused this implementation.

Credit is given where credit is due.

于 2016-02-17T17:37:27.340 回答