Can ContinueWith be used as the โ€œfinalโ€ operation?

Consider a code snippet, for example:

private Task<string> Download() { var wc = new WebClient(); Task<string> backgroundDownload = wc.DownloadStringTaskAsync(this.Uri); // Make sure the WebClient is disposed no matter what. backgroundDownload.ContinueWith((downloadTask) => { wc.Dispose(); }); return backgroundDownload; } 

Can I be sure that a call to WebClient.Dispose() happening and that any exception thrown is returned to the caller, as if there was no call to ContinueWith ?

Can customers watch this ContinueWith ? (for example, later calls ContinueWith remove the Dispose call?)

+5
source share
2 answers

With the code that you have, you can be sure that the continuation will be fired regardless of whether the code completed successfully, canceled or thrown an exception.

One potential problem with the solution you have is that other extensions can potentially start before, during, or after the web client has been removed. If you have no problems with other extensions running before this cleanup is started, then you are fine. If this is a problem, you will need to return the continuation, not the original task, but you also need to correctly distribute the result (and exceptions / cancellations). Using async makes it all easier:

 private async Task<string> Download() { using(var wc = new WebClient()) return await wc.DownloadStringTaskAsync(this.Uri); } 
+11
source

First of all, the continuation will be executed even if a regular exception has occurred. However, it is less likely than a regular finally block in the case of exceptional conditions, such as an OutOfMemoryException.

Now I would not try to rid the web client. Remember that recycling is an optimization, since in any case local resources will be installed by the finalizer. The only reason we get rid of is because the finalizer is expensive because it launches the second pass of the GC.

But to complete your optimization, the system may have to create new threads. In addition, you can extend the life of your web client a lot if the threadpool is full of long jobs.

Basically, you need to choose the lesser of two evils, and I'm not sure if one less fast GC launch is worth what you are doing. You should consider this solution in the context of your application.

0
source

Source: https://habr.com/ru/post/1203256/


All Articles