Im trying to execute two different tasks from async methods but my second task only should start where the first ends. I've tryed to use ContinueWith but with no success. This is my sample code :
class Program
{
static List<string> GlobalList1 = null;
static List<string> GlobalList2 = null;
static void Main(string[] args)
{
Task firstTask = new Task(DoFirstThing);
firstTask.Start();
firstTask.Wait();
Task secondTask = firstTask.ContinueWith(o => DoSecondThing(), TaskContinuationOptions.ExecuteSynchronously);
secondTask.Wait();
Console.ReadKey();
}
public async static void DoFirstThing()
{
Console.WriteLine("Doing first...");
Task t = new Task(FirstThing);
t.Start();
await t;
}
public async static void DoSecondThing()
{
Console.WriteLine("Doing second...");
Task t = new Task(SecondThing);
t.Start();
await t;
}
private async static void FirstThing()
{
Console.WriteLine("In First..");
Task t = new Task(() =>
{
List<string> list = new List<string>();
for (int i = 0; i < 1000; i++)
{
list.Add(string.Format("Testing:{0}", i));
}
System.Threading.Thread.Sleep(2000);
GlobalList1 = list;
});
t.Start();
await t;
}
private async static void SecondThing()
{
Console.WriteLine("In Second...");
Task t = new Task(() =>
{
GlobalList2 = new List<string>();
for (int i = 0; i < GlobalList1.Count; i++)
{
GlobalList2.Add(GlobalList1[i].ToString() + " - testing");
}
});
t.Start();
await t;
}
}
You may notice by the console output that tasks keep running at same time. Is it possible to change this behaviour ?
my second task only should start where the first ends
Then you should genuinely wait for it to finish. Currently, you're not doing so. You're waiting for the DoFirstThing
method to return, but it will do so before it finishes awaiting t
.
If instead of constructing a new Task
and then calling Start()
, you call Task.Run
and provide a Func<T>
, you can wait for the proxy task to complete:
static void Main(string[] args)
{
Task firstTask = Task.Run(DoFirstThing);
firstTask.Wait();
...
}
public async static Task DoFirstThing()
{
Console.WriteLine("Doing first...");
Task t = Task.Run(FirstThing);
await t;
}
private async static Task FirstThing() { ... }
Now the Wait()
call will not complete until the FirstThing()
asynchronous operation has genuinely completed.
Basically, avoid async void
methods in almost all cases.
That said:
Wait()
rather than awaiting a task is also rarely a good idea, as it can deadlock if the given task has a continuation that has to run on the same thread.See more on this question at Stackoverflow