简体   繁体   中英

How to dispose a Task as soon as possible

I have a Windows form application that i want on each OnLoad to start an async Task that gets disposed on the next OnLoad .

After running with the Profiler i see that the object count gets bigger and bigger after each OnLoad . I know that the GC does not free the memory right when you call Dispose nor when you set to null .Should i override the finalizer ? I have also considered a CancellationTokenSource but i

Form

public class MyForm:Form
{
   private Task task;
   protected override OnLoad()
   {
     if(this.task!=null)
     {
          this.task.Dispose();
          this.task=null;
     }
     this.task=Task.Run(()=>....);
   }
}

With Token

public class MyForm:Form
    {
       private Task task;
       private CancellationTokenSource=new CancellationTokenSource();
       protected override OnLoad()
       {
         if(this.task!=null)
         {
              src.Cancel();
         }
         try
         {
         this.task=Task.Run(()=>....,src.Token);
         }catch(TaskCancelledException ex)
         {
              return;
         }

       }
    }

The problem with CancellationTokenSource is that as you can see i would call Cancel on a previous Task (At the second OnLoad call i would dispose the first Task ) and i do not know if that would get handled in the Try-Catch block.

What would be a good method to dispose the Task object as soon as possible ? This Form would reload continously on a computer at timed intervals, and i do not want to dispose it, just the Task

You do not have to dispose of the tasks in your situation. It only implements IDisposable because it may allocate a WaitHandle (which is disposable):

Internally, Task may allocate a WaitHandle which can be used to wait on the Task to complete. WaitHandle is IDisposable because it holds onto a SafeWaitHandle internally, which is IDisposable. SafeWaitHandle wraps a native handle resource: if the SafeWaitHandle isn't disposed, eventually its finalizer will get around to cleaning up the wrapped handle, but in the meantime its resources won't be cleaned up and pressure will be put on the system. By implementing IDisposable on Task, then, we enable developers concerned about aggressively cleaning up these resources to do so in a timely manner.

Now, Microsoft did realize this can create confusion so they made some changes and created some guidance:

We've made it much less likely that the Task's WaitHandle will be allocated at all. We've re-implemented WaitAll and WaitAny so that they don't rely on a Task's WaitHandle, and we've avoided using it internally for any of the new Task or async/await-related functionality introduced in .NET 4.5. Thus, the only way the WaitHandle will be allocated is if you explicitly ask for the Task's IAsyncResult.AsyncWaitHandle, and that should be quite rare. This means that except in such very infrequent circumstances, disposing of a Task is completely unnecessary.

and

We've made Tasks usable even after they've been disposed. You can now use all of the public members of Task even after its disposal, and they'll behave just as they did before disposal. The only member you can't use is IAsyncResult.AsyncWaitHandle, since that's what actually gets disposed when you dispose of a Task instance; that property will continue to throw an ObjectDisposedException if you try to use it after the Task has been disposed. This means you should feel freely comfortable caching completed Tasks, knowing that they're observationally pure. Additionally, moving forward, IAsyncResult usage should drop significantly now that we have async/await and the Task-based Async Pattern, and even for continued usage of IAsyncResult, usage of its AsyncWaitHandle is quite rare.

The basic advice however is:

“No. Don't bother disposing of your tasks.” It's often difficult to find a good place to do so, there's almost never a reason to do so, and depending on your reference assemblies, you might not even be able to do so.

( source )

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM