Running a longProcess() method in one of my C# api and while doing that we want to wait for that task to complete. But same time don't want to block the UI. I saw many SO threads, but nothing helps in my case. Below, Method 1 does not block UI and Method 2, blocks/freezes UI. Any thoughts?
public class MyApiManager
{
private string _x;
public MyApiManager(string x)
{
_x = x;
}
public void DoProcess()
{
// Method 1: Does NOT block UI, but does not wait either
Task task = Task.Factory.StartNew(() =>
{
Task longProcess = Task.Factory.StartNew(new Action(longProcess));
});
task.Wait();
// Method 2: BLOCKS UI, also waits
//var context = TaskScheduler.FromCurrentSynchronizationContext();
//Task task = Task.Factory.StartNew(() =>
//{
// var token = Task.Factory.CancellationToken;
// Task.Factory.StartNew(() =>
// {
// longProcess();
// }, token, TaskCreationOptions.None, context);
//});
//task.Wait();
}
private void longProcess()
{
// simulate long process
Thread.Sleep(10000);
}
}
First off, you need to separate your concerns.
MyApiManager
should not know anything about UIs. It manages APIs, and according to the Single Responsibility Principle, that's all it does.Read Stephen Toub's Should I expose synchronous wrappers for asynchronous methods?
It should be the UI event handler's responsibility to make sure
MyApiManager
does not block the UI. So, change your event handler to something like this:Both of your approaches are overly complicated, you're wrapping tasks within tasks, within tasks... Simply use
await Task.Run
, that's all you need.