Can't dispose StreamSocket

1k views Asked by At

I've made a small class that connects to and IRC server, and now I'm trying to dispose of the socket.

Whenever I do so, i'm getting a

The I/O operation has been aborted because of either a thread exit or an application request

It's maybe worth noting that I'm calling the dispose function

protected override void OnNavigatedFrom(NavigationEventArgs e)

I've also tried Detaching the Stream from the DataReader before disposing the StreamSocket, but it still won't work. In fact it is raising another error.

The operation identifier is not valid

How else am I supposed to dispose of the StreamSocket?

This is how I imagined the Dipose method should look like:

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

When I connect I do it like so:

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

The read data method is recursive and keeps on reading any incoming data:

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

There are 1 answers

1
kiewic On BEST ANSWER

You will need to cancel the read operation on the socket first. Fort his, use a CancellationToken.

Create a global CancellationTokenSource:

CancellationTokenSource cancellationTokenSource = new CancellationTokenSource();

When calling DataReader.LoadAsync() pass a token:

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

Finally, when you want to abandon everything, call cancel:

cancellationTokenSource.Cancel();

However, in this case, the LoadAsync() call will end with TaskCanceledException.

You don't need to dispose the socket anymore, the socket will be closed as part of cancelling the read operation.