2014-11-23 4 views
0

Я сделал небольшой класс, который подключается к серверу IRC, и теперь я пытаюсь избавиться от сокета.Нельзя утилизировать StreamSocket

Всякий раз, когда я так, я получаю

Операция ввода/вывода была прервана из-за выхода потока или запрос приложения

Это может быть, стоит отметить, что Я вызываю функцию Dispose

protected override void OnNavigatedFrom(NavigationEventArgs e) 

Я также попытался Отсоединением потока из DataReader перед утилизацией в StreamSo cket, но он все равно не сработает. На самом деле это вызывает еще одну ошибку.

Операция идентификатор не является действительным

Как еще я должен распоряжаться StreamSocket?

Это, как я представлял себе метод Dipose должен выглядеть следующим образом:

public async void Dispose() 
{ 
    _closing = true; 
    if (_connected) 
      SendRawMessage("QUIT :"); 
    //_dataReader.DetachStream(); 
    await _clientSocket.DisposeAsync(); 
    _dataReader.Dispose(); 
    _connected = false; 
    _closing = false; 
} 

Когда я подключаю я делаю это так:

await _clientSocket.ConnectAsync(hostname, Port.ToString()); 
_connected = true; 
_dataReader = new DataReader(_clientSocket.InputStream) { InputStreamOptions = InputStreamOptions.Partial }; 
ReadData(); 

Метод Считанные данные рекурсивная и продолжает читать любой входящие данные:

async private void ReadData() { 
    if (!_connected || _clientSocket == null || _closing == true) return; 
    uint s = await _dataReader.LoadAsync(1024); 
    string data = _dataReader.ReadString(s); 
    ReadData(); 
} 
+0

Вы используете его во время использования сокета, активно пытающегося получить что-то. Это нормально, но, конечно, вы получаете исключение «это не нормально», когда получение завершается, оно фактически ничего не получает. Предложение «или запрос заявки» явно применяется. Поскольку вы полностью ожидаете, что это произойдет, вы можете поймать исключение. Опубликуйте лучшие фрагменты, если вам нужна дополнительная помощь. –

+0

Но вызов DeteachStream на datareader, разве это не мешает ему активно пытаться получать данные? – Jazerix

+0

Я добавил еще один код, чтобы показать контекст :) – Jazerix

ответ

0

Сначала вам необходимо отменить операцию чтения на сокете. Форт его, используйте CancellationToken.

Создание глобальной CancellationTokenSource:

CancellationTokenSource cancellationTokenSource = new CancellationTokenSource(); 

При вызове DataReader.LoadAsync() передать маркер:

uint s = await _dataReader.LoadAsync(1024).AsTask(
    cancellationTokenSource.Token); 

Наконец, если вы хотите отказаться от всего, назвать отменить:

cancellationTokenSource.Cancel(); 

Однако , в этом случае вызов LoadAsync() закончится остроумием h TaskCanceledException.

Вам больше не нужно устанавливать гнездо, гнездо будет закрыто как часть отмены операции чтения.

+0

Это, кажется, работает очень хорошо :) Как вы подавляете исключение TaskCanceledException? В настоящее время я только что поместил функцию в блок catch try, это приемлемо или есть лучший способ? – Jazerix

Смежные вопросы