Collectives™ on Stack Overflow

Find centralized, trusted content and collaborate around the technologies you use most.

Learn more about Collectives

Teams

Q&A for work

Connect and share knowledge within a single location that is structured and easy to search.

Learn more about Teams

I use SendAsync with HttpCompletionOption.ResponseHeadersRead to get the headers first. Next I check the Content-Type and Content-Length to make sure the response is markup and the size is decent. I use a CancellationTokenSource to cancel the SendAsync if it exceeds a certain timespan.

But then, if the type and size are correct, I continue to actually fetch the markup string with ReadAsStringAsync . Can I add a cancellation token to this call? So if the actual download takes too long, I can abort it. Or can this be done in any other way?

I don't want to use GetStringAsync as I use a custom HttpRequestMessage .

PS : I'm rather new to C#, 2 weeks. Something might be eluding me.

Does ReadAsStringAsync() actually continue to block if you use your existing CancellationTokenSource and/or dispose of your HttpContent object? It looks as if ReadAsStringAsync() is designed to never actually need a cancellation token, because the operation will already get cancelled when appropriate. (But I can't actually try it right now, so I don't know if this is right, and if it is, which of the two approaches works.) user743382 Aug 9, 2014 at 14:26 @hvd I use CancellationToken in SendAsync but I use the flag to just fetch headers first. Content is (should not be) fetched until I use ReadAsStringAsync() . So in HTTP, first step reads the headers, second read the actual data stream. I'd like to cancel inside the data stream without leaving dangling Tasks. CodeAngry Aug 9, 2014 at 14:32 I understand that. I'm trying to say that it seems like that second operation can already be cancelled, without having to send a second cancellation token, but that I don't see exactly how. If you can't get something working from my comment, I'll test when I get the chance, but that won't be today. user743382 Aug 9, 2014 at 14:44 @hvd I'm current using WithCancellation mentioned in the answer. But this leaves dangling tasks. I will test to see if the SendAsync cancellation token still works in the ReadAsStringAsync but I need to setup a specialized test case. So I'll write a local web server to send content back very slow so I can cancel before it's all sent... CodeAngry Aug 9, 2014 at 15:31

No, you can't. There's no overload of ReadAsStringAsync that accepts a cancellation token and you can't cancel a non-cancelable async operation .

You can however abandon that operation and move on with a WithCancellation extension method, which won't actually cancel the operation but will let the code flow as if it has been:

static Task<T> WithCancellation<T>(this Task<T> task, CancellationToken cancellationToken)
    return task.IsCompleted
        ? task
        : task.ContinueWith(
            completedTask => completedTask.GetAwaiter().GetResult(),
            cancellationToken,
            TaskContinuationOptions.ExecuteSynchronously,
            TaskScheduler.Default);
                Noticed that comment also. Trying it now but not too happy to leave the Tasks afloat... ReadString() implies multiple socket reads until the entire response is fetched. It should have CancellationToken support as it has the chance to cancel between those reads.
– CodeAngry
                Aug 9, 2014 at 14:10
                I found in a UWP app that if an exception occurred in the wrapped task, it wasn't picked up by the code awaiting on the WithCancellation task. The program terminated with an unhandled exception.
– Edward Brey
                Aug 21, 2019 at 17:12
                @EdwardBrey UnobservedTaskException I assume. Yes, it's important to always await tasks or otherwise check if they resulted in an exception. I learned that the exact same way, with a Windows App. :)
– AyCe
                Mar 9, 2022 at 20:01
                On second thought, this might not be correct. It depends on the scope of cancelation for HttpClient, which isn't documented. I created an issue to clarify.
– Edward Brey
                Jul 23, 2018 at 21:34
        

Thanks for contributing an answer to Stack Overflow!

  • Please be sure to answer the question. Provide details and share your research!

But avoid

  • Asking for help, clarification, or responding to other answers.
  • Making statements based on opinion; back them up with references or personal experience.

To learn more, see our tips on writing great answers.