So I was working on this CefSharp Chromium project where we needed to interact with the DOM in Chromium. We were trying to automate Order creation for a portal where-in we needed to click buttons in the portal’s html manually, and wait for their Ajax requests to complete before we could proceed with further interactions with the DOM.

So I chained together a series of DOM interaction calls interlaced with Task Delay calls like below:

Task
	.Delay(1000)
	.ContinueWith(t1 =>
	{
		var script = @"
--Some DOM intertaction script
";

		base.executeScript(script);
	})
	.ContinueWith(async t2 =>
	{
		//Allow Delivery Code logic to be processed.
		await Task
			.Delay(3000);
	})
	.ContinueWith(t3 =>
	{
		var script = @"
--Some DOM intertaction script
";

		base.executeScript(script);
	});

I was expecting the Task t3’s callback to be executed after a Delay of 3 seconds introduced in Task t2. However to my surprise, Task t3 was being executed immediately after Task t1.

Upon some research, I stumbled upon something really interesting:
ContinueWith returns a Task<Task> which does not wait for the Delay Task to be completed. For more details check this link: https://stackoverflow.com/a/36991693.

The solution was simple, adding an Unwrap call after task t2 made the Task t3 to be properly delayed for 3 seconds after Task t1. For completeness sake, here’s updated code:

Task
	.Delay(1000)
	.ContinueWith(t1 =>
	{
		var script = @"
--Some DOM intertaction script
";

		base.executeScript(script);
	})
	.ContinueWith(async t2 =>
	{
		//Allow Delivery Code logic to be processed.
		await Task
			.Delay(3000);
	})
	.Unwrap()
	.ContinueWith(t3 =>
	{
		var script = @"
--Some DOM intertaction script
";

		base.executeScript(script);
	});

Happy learning!! 🙂