Сбой метода чтения после получения нескольких пакетов

Мое приложение отправляет учетные данные пользователей на сервер, если они верны, сервер отправляет пакет, сообщая клиенту, что его учетные данные неверны или верны. После нескольких фиктивных тестов мой клиент завис из-за этой строки кода;

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

Исключение типа "System.ObjectDisposedException" произошло в MobileApp.exe, но не было обработано в коде пользователя

Исключение одноразового использования объекта не было обработано кодом пользователя.

2 ответа

Решение

Вы переходите в сложные воды, когда вызываете LoadAsync из асинхронного метода. Метод LoadAsync должен вызываться только один раз из потока пользовательского интерфейса. Метод не может быть вызван снова, пока не будет вызвано событие LoadCompleted. Скорее всего, вы звоните во второй раз, прежде чем предыдущий запрос будет завершен.

Попробуйте переключить оскорбительную строку ожидания на что-то вроде этого:

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

Если вы хотите получить очень длинный ответ, который будет более подробным, посмотрите этот ответ: /questions/44232435/ispolzuyutsya-li-v-novyih-klyuchevyih-slovah-c-50-async-i-await-neskolko-yader/44232458#44232458

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

Благодаря Ageonix, я смог прийти к такому выводу благодаря его ответу, который вызвал эту реализацию.

Кредит дается там, где кредит должен.

Другие вопросы по тегам