0

My understanding is that if you call async code synchronously it can cause deadlock when it needs to synchronize back to the UI thread to modify UI elements or if you need to access ASP.NET HttpContext.Current. There are workarounds to solve this problem as mentioned here:

I was looking at the "The Thread Pool Hack" approach from the first link but I need to call GetAwaiter().GetResult() directly from the async code which is already called from a new thread e.g:

//MyWork.DoWork must execute in a separate thread due legacy code that I can't refactor right now.

public class SomeClass {
  try {
     var myThread = new Thread(MyWork.DoWork);
     myThread.Start();
   } catch (Exception ex) {
       //Handle exceptions
   }
}

public class MyWork {
  public static bool DoWork(){
      var response = MyHttpClient.MakeRequestAsync(params)
                    .GetAwaiter()
                    .GetResult();

      if(!response.Succeed){
        //add logs and other stuff
      }
  }      
}

Also my call to MyHttpClient.MakeRequestAsync is NOT using .ConfigureAwait(false); and I can't add that since the same calls can be used in other places where it may need to synchronize back to the UI context

  • Is it safe to call .GetAwaiter().GetResult() directly on MyHttpClient.MakeRequestAsync since I'm already starting the work in a separate thread?
  • Once the MyHttpClient.MakeRequestAsync resumes will it resume the work in the same thread?

Update: I cannot let the async pattern propagate I must use existing legacy code that uses the thread class so no refactoring allowed at the moment for SomeClass.

Theodor Zoulias
  • 34,835
  • 7
  • 69
  • 104
Goca
  • 1,743
  • 2
  • 15
  • 36
  • 3
    Why do you need to do this? Why not just use the async await pattern and let it propagate ? Also why are you using the Thread class. Because, at the moment this is not the optimal way to do IO workloads, and async calls (in modern .net) – TheGeneral Mar 11 '21 at 02:59
  • 1
    And, that's not a thread pool thread. That's just a thread – Flydog57 Mar 11 '21 at 03:05
  • Also `new Thread(` is not the threadpool hack, the example uses `task.Run` to offload the async work to a thread pool thread, then uses `.GetAwaiter().GetResult()` to block unwrap the result. – TheGeneral Mar 11 '21 at 03:05
  • 1
    Anyway, to answer the questions. There is no dispatcher or messagepump or sync context on the thread you are creating which means there is no deadlock, secondly, when you call `.GetAwaiter().GetResult()` it is calling and blocking on the current thread, which is just a random thread you spun up. However, i would really reconsider this design, sooner or later you will need to refactor this anyway – TheGeneral Mar 11 '21 at 03:11
  • There is a bunch of legacy code that I'm not allow to refactor right now, the someClass code is just an abstract of the main code, we are doing a loop to check for work that need to run in the background, the MakeRequestAsync is newer code which was designed as async the problem is that I need to call this from this legacy code so I need to play by the existing rules. – Goca Mar 11 '21 at 04:18
  • @TheGeneral thanks for answering my questions as long as it will not cause a deadlock it should be fine for now, I agree this needs to be refactored but at the moment that is not possible company politics bs – Goca Mar 11 '21 at 04:19

0 Answers0