0 votes
ago by (2.2k points)

I want to cancel a Read call that has a very long delay after establishing an HTTP connection.

Will it be possible to cancel quickly using Cancellation.Register(() => stream.Close()) as shown below?

Please let me know if there is a correct cancellation method.

Current method in use (simplified)

try
{
    var stream = response.GetResponseStream();
    using var registration = canceltoken.Register(()=> stream.Close());
    while(canceltoken.IsCancellationRequested == false)
    {
        var data = stream.Read(buffer, 0, length);
        ...
    }
}
catch(Exception) when (cancelToken.IsCancellationRequested)
{
    canceled = true;
}
catch(Exception ex)
{
    error = ex.Message;
}
Applies to: Rebex HTTPS

1 Answer

+1 vote
ago by (77.9k points)
selected ago by
 
Best answer

For cancelling a request/reponse you can use the WebRequest.Abort() method. The solution can look like this:

// create request
var request = creator.Create(url);

// register call to the Abort() method
canceltoken.Register(request.Abort);

try
{
    // work with Request/Response/ResponseStream as noramlly
    var response = request.GetResponse();
    // ...
}
catch (WebException ex)
{
    // check whether the request was cancelled or we got a different error
    if (ex.Status == WebExceptionStatus.RequestCanceled)
        canceled = true;
    else
        error = ex.Message;
}

Using the Abort() method allows you to cancel the request in any state (sending request, reading response headers, reading response data).

ago by (2.2k points)
If I cannot use `request.Abort` when the function receiving the HTTP response is different from the function receiving the data, would it be okay to use `stream.Close` instead?

I plan to use `request.Abort` where everything is processed at once, and `stream.Close` where processing is separated.
ago by (77.9k points)
In general yes. If you call the stream.Close() method, the existing HTTP(S) connection will be forcefully closed. The state of the ResponseStream will be undefined and you will receive the ObjectDisposedException when accessing it.
...