Reputation: 1442
I'm writing a simple console application that should make requests to different external sources and return the response from whichever source answers first.
I'm trying to do this using Task
objects (to keep the code as simple as possible), but my program deadlocks and never completes execution. Now, I suspect that it's because I'm using Result
on my tasks, but I have no idea how to make it work without the Result
.
public static string GetResultFromAnySource()
{
var t1 = new Task<string>(() => { Thread.Sleep(500); return "Result from source 1"; });
var t2 = new Task<string>(() => { Thread.Sleep(100); return "Result from source 2"; });
var res = Task.WhenAny(t1, t2).Result;
if (res == t1)
return "Source 1 was faster. Result: " + t1.Result;
else if (res == t2)
return "Source 2 was faster. Result: " + t2.Result;
throw new ApplicationException("Something went very wrong");
}
static void Main(string[] args)
{
Console.WriteLine(GetResultFromAnySource());
}
Any help is appreciated.
Upvotes: 0
Views: 3248
Reputation: 2323
Hi Andre I rewrote your program by using async/await keywords:
class Program {
public static async Task<string> GetResultFromAnySource() {
var t1 = Task<string>.Run( () => { Task.Delay(500).Wait(); return "Result from source 1"; });
var t2 = Task<string>.Run(() => { Task.Delay(100).Wait(); return "Result from source 2"; });
var res = await Task.WhenAny(t1, t2);
if (res == t1)
return "Source 1 was faster. Result: " + await t1;
else if (res == t2)
return "Source 2 was faster. Result: " + await t2;
throw new ApplicationException("Something went very wrong");
}
static void Main(string[] args) {
Task.Run(async () => await Out()).Wait();
}
static async Task Out()
{
var str = await GetResultFromAnySource();
Console.WriteLine(str);
}
}
It is recommended to use Task.Run - the code is clear and it starts the task immediately.
Upvotes: 4
Reputation: 7622
You missed to start the tasks.
t1.Start();
t2.Start();
Alternatively, use Task.Run()
var t1 = Task.Run<string>(() => { Thread.Sleep(500); return "Result from source 1"; });
var t2 = Task.Run<string>(() => { Thread.Sleep(100); return "Result from source 2"; });
Upvotes: 3