title: Syncronization of async EF Tasks
body: <p>I am working on an Application to processes Company resources. We have a MS SQL Database and are working with EntityFramework 6.1.3 and .Net4.5.
  Now DbContext has async methods for example</p>
  
  <pre><code>protected Task&lt;int&gt; SaveChangesAsync();
  </code></pre>
  
  <p>I know that DbContext is NOT Thread safe and I dont want to actually call Async operations with the intend that they will be executed parallel. But I need to free up my GUI thread while polling the database.</p>
  
  <p>Normally you would go and programm with await keywords and "just be carefull" not to call 2 Async operations at the same time BUT the application is supposed to be always up-to-date. Therefor we have a server connection. Now everytime some other user updates the database a polling command is sent to all Applications that are currently working on this database. This polling command could be anytime and would therefor be a racecondition with any user initiated async polling of the database.</p>
  
  <p>What I want to do is queue each Task after the previous one. BUT I dont really know how to or if that even is a good idea.
  So far I tried working with Task.ContinueWith() but noticed that my Tasks are never starting and therefor I wait forever.</p>
  
  <p>Here would be the code so far<br>
  (_lastRunningTask is declared in my DbContext inhereting class and initialized in the constructor with :</p>
  
  <pre><code>_lastRunningTask = Task.Run(() =&gt; { Thread.Sleep(1); });
  </code></pre>
  
  <p>)</p>
  
  <pre><code>private Task _lastRunningTask;
  
  private Task&lt;int&gt; SaveChangesAsyncImpl(CancellationToken cancellationToken)
      {
          return ValidateEntitiesAsyncImpl().ContinueWith(p =&gt; SaveChangesAsync(cancellationToken)).Unwrap();
      }
  
      public override int SaveChanges()
      {
  
          Task&lt;int&gt; t = _lastRunningTask.ContinueWith(p =&gt; SaveChangesAsyncImpl(CancellationToken.None)).Unwrap();
  
          _lastRunningTask = t;
  
          return t.Result;
      }
      public override Task&lt;int&gt; SaveChangesAsync()
      {
          return SaveChangesAsync(CancellationToken.None);
      }
      public override Task&lt;int&gt; SaveChangesAsync(CancellationToken cancellationToken)
      {
          Task&lt;int&gt; t = _lastRunningTask.ContinueWith(p =&gt; SaveChangesAsyncImpl(cancellationToken)).Unwrap();
          _lastRunningTask = t;
          return t;
      }
  
  
  
  
      public Task ValidateEntitiesAsync()
      {
          return _lastRunningTask = _lastRunningTask.ContinueWith(p =&gt; ValidateEntitiesAsyncImpl()).Unwrap();
      }
  
      private Task ValidateEntitiesAsyncImpl()
      {
          return Task.Run(() =&gt;
          {
              ChangeTracker.DetectChanges();
              List&lt;DbEntityEntry&gt; AllEntites = new List&lt;DbEntityEntry&gt;(ChangeTracker.Entries());
  
              try
              {
                  foreach (DbEntityEntry entity in AllEntites)
                  {
                      if (entity.State == EntityState.Deleted)
                          ((EntityBase)entity.Entity).readyToDelete();
                  }
              }
              catch (ErrorException e)
              {
                  fireError(e);
                  throw e;
              }
              catch (Exception e)
              {
                  return;
              }
              return;
          });
      }
  
      public Task RevertChangesAsync&lt;TEntity&gt;(CancellationToken token) 
          where TEntity : EntityBase
      {
          return _lastRunningTask = _lastRunningTask.ContinueWith(p =&gt; RevertChangesAsync&lt;TEntity&gt;(token)).Unwrap();
      }
  
      private Task RevertChangesAsyncImpl&lt;TEntity&gt;(CancellationToken token) where TEntity : EntityBase
      {
          return Task.Run(() =&gt; revertDummy&lt;TEntity&gt;(token));
      }
      private async void revertDummy&lt;TEntity&gt;(CancellationToken token) where TEntity : EntityBase
      {
          ChangeTracker.DetectChanges();
          List&lt;DbEntityEntry&lt;TEntity&gt;&gt; revertEntries = new List&lt;DbEntityEntry&lt;TEntity&gt;&gt;(ChangeTracker.Entries&lt;TEntity&gt;());
  
          foreach (DbEntityEntry entity in revertEntries)
          {
              await entity.ReloadAsync(token);
          }
      }
  </code></pre>