async/await not working in console application - c#

I'm totally green with TPL and want to execute an async method in a console application.
My code:
static void Main()
{
Task<string> t = MainAsync();
t.Wait();
Console.ReadLine();
}
static async Task<string> MainAsync()
{
var result = await (new Task<string>(() => { return "Test"; }));
return result;
}
This task runs forever. Why? What am I missing?

You don't start your task. This is why Wait doesn't return. Try
var result = await Task.Run<string>(() => { return "Test"; });

Related

Task caused UI Freezing - WPF

The structure of my code is shown below:
internal async Task ButtonClickMethod()
{
await this.InitializeMethod();
}
internal async Task InitializeMethod()
{
await this.Call();
}
private async Task Call()
{
await this.CallTasks();
}
private async Task CallTasks()
{
List<Task> tasks = new List<Task>();
tasks.Add(/*time-consuming task A*/);
tasks.Add(/*time-consuming task B*/);
tasks.Add(/*time-consuming task C*/);
tasks.Add(/*time-consuming task D*/);
await Task.WhenAll(tasks);
}
Task defined as follows:
/*time-consuming task*/
internal async Task TimeConsuming()
{
// code...
await Task.Run(() =>
{
// code... A/B/C/D
});
// code...
}
Is there any problem with this code that will cause the UI to freeze?
Is the problem caused by Task.WhenAll?
Use this instead :
private async void ClickButton(object sender, RoutedEventArgs e)
{
await ThatFirstMethod(any parameters);
}
private async Task ThatFirstMethod(any parameters)
{
await Task.Run(() => {
ThatFirstTimeConsumingMethod(any param);
});
await Task.Run(() => {
ThatSecondTimeConsumingMethod(any param);
});
}
private bool ThatFirstTimeConsumingMethod(any param)
{
//code
return true;
}
.....
If you have to access UI Elements you will not be able to do so, beacause your "heavy" methods are being processed by another Thread.
Here's a solution :
private bool ThatFirstTimeConsumingMethod(any param)
{
string s = "";
Application.Current.Dispatcher.Invoke(() => {
s = myTextBox.Text;
});
// do what you want with the s variable
Application.Current.Dispatcher.Invoke(() => {
myTextBox.Text = s;
});
return true;
}
So basically, you're asking your main Thread to execute an action (where your UI is getting processed) with Application.Current.Dispatcher.Invoke. And when you're in the await Task.Run you're asking another thread to process the heavy action.

Run Multiple HttpResponseMessage Task in a sequence

In a console application I've created a List of Task in which im adding three async tasks:
static void Main(string[] args)
{
List<Task> task_list= new List<Task>();
Task task_1=new Task(async () => await Task_method1());
Task task_2=new Task(async () => await Task_method2());
Task task_3=new Task(async () => await Task_method3());
task_list.Add(task_1);
task_list.Add(task_2);
task_list.Add(task_3);
Task.WaitAll(task_list.ToArray());
foreach (Task t in task_list)
{
Console.WriteLine("Task {0} Status: {1}", t.Id, t.Status);
}
Console.ReadKey();
}
And here's the method definition of 3 Task:
public async Task<HttpResponseMessage> Task_Method1()
{
//Code for Response
return Response;
}
public async Task<HttpResponseMessage> Task_Method2()
{
//Code for Response
return Response;
}
public async Task<HttpResponseMessage> Task_Method3()
{
//Code for Response
return Response;
}
Problem is that they are running parallely, and there's no serialized order of tasks. I searched a lot but get didn't get an appropriate solution for running them in series.
For reference see the image below:
RUN1:
RUN2:
RUN3:
You must have omitted some code, as even if the tasks complete in arbitrary order, your List's order should remain unchanged, yet you show your output with the List's order changing.
Then re actually doing it, perhaps I'm missing something, but if you want them to run in order why not just do:
static void Main(string[] args)
{
MainAsync().Wait();
}
private async Task MainAsync()
{
var response1 = await Task_method1();
var response2 = await Task_method2();
var response3 = await Task_method3();
// Write results, etc.
Console.ReadKey();
}

Using Func delegate with Async method

I am trying to use Func with Async Method. And I am getting an error.
Cannot convert async lambda expression to delegate type 'Func<HttpResponseMesage>'. An async lambda expression may return void, Task or Task<T>, none of which are convertible to 'Func<HttpResponseMesage>'.
below is my Code:
public async Task<HttpResponseMessage> CallAsyncMethod()
{
Console.WriteLine("Calling Youtube");
HttpClient client = new HttpClient();
var response = await client.GetAsync("https://www.youtube.com/watch?v=_OBlgSz8sSM");
Console.WriteLine("Got Response from youtube");
return response;
}
static void Main(string[] args)
{
Program p = new Program();
Task<HttpResponseMessage> myTask = p.CallAsyncMethod();
Func<HttpResponseMessage> myFun =async () => await myTask;
Console.ReadLine();
}
As the error says, async methods return Task,Task<T> or void. So to get this to work you can:
Func<Task<HttpResponseMessage>> myFun = async () => await myTask;
The path I usually take is to have the Main method invoke a Run() method that returns a Task, and .Wait() on the Task to complete.
class Program
{
public static async Task<HttpResponseMessage> CallAsyncMethod()
{
Console.WriteLine("Calling Youtube");
HttpClient client = new HttpClient();
var response = await client.GetAsync("https://www.youtube.com/watch?v=_OBlgSz8sSM");
Console.WriteLine("Got Response from youtube");
return response;
}
private static async Task Run()
{
HttpResponseMessage response = await CallAsyncMethod();
Console.ReadLine();
}
static void Main(string[] args)
{
Run().Wait();
}
}
This allows the rest of your Console app to run with full async/await support. Since there isn't any UI thread in a console app, you don't run the risk of deadlocking with the usage of .Wait().
Code fix such as:
static void Main(string[] args)
{
Program p = new Program();
Task<HttpResponseMessage> myTask = p.CallAsyncMethod();
Func<Task<HttpResponseMessage>> myFun = async () => await myTask;
Console.ReadLine();
}
Inside the Func run the task, wait for it and check for exception, then return the result.
Func<HttpResponseMessage> myFun = () =>
{
var t = Task.Run(async () => await myTask);
t.Wait();
if (t.IsFaulted)
throw t.Exception;
return t.Result;
};

Async/Await - Vicious Circle C# 5.0

The code is below.
I want to call DoLongWork function asynchronously.
But the code ends up synchronous because DoLongWork doesn't await anything.
There is no need for awaiting something in DoLongWork function. Because function itself is long running. Not waiting any resource.
How can I get out of this vicious circle?
class Program
{
static void Main(string[] args)
{
Task<int> task = Foo("Something");
Console.WriteLine("Do it");
Console.WriteLine("Do that");
task.Wait();
Console.WriteLine("Ending All");
}
static async Task<int> Foo(string param)
{
Task<int> lwAsync = DoLongWork(param);
int res = await lwAsync;
return res;
}
static async Task<int> DoLongWork(string param)
{
Console.WriteLine("Long Running Work is starting");
Thread.Sleep(3000); // Simulating long work.
Console.WriteLine("Long Running Work is ending");
return 0;
}
}
You can use Task.Run to execute synchronous work on a background thread:
// naturally synchronous, so don't use "async"
static int DoLongWork(string param)
{
Console.WriteLine("Long Running Work is starting");
Thread.Sleep(3000); // Simulating long work.
Console.WriteLine("Long Running Work is ending");
return 0;
}
static async Task<int> FooAsync(string param)
{
Task<int> lwAsync = Task.Run(() => DoLongWork(param));
int res = await lwAsync;
return res;
}

How to get asynchronousy without new threads or async and await keywords but only Task

I wonder how to accomplish the same thing the below program does without using extra threads or await and async keywords but only Tasks. A sample code would be awesome. It seems to me that we need to use TaskCompletionSource and Async versions of the IO-bound operations or any long-running operations.
static void Main(string[] args)
{
Task t = Go();
Console.WriteLine("Hello World");
Task.Delay(1000).GetAwaiter().OnCompleted(() => { Console.WriteLine("Completed"); });
Console.ReadLine();
}
static async Task Go()
{
var task = PrintAnswerToLife();
await task;
Console.WriteLine("Done");
}
static async Task PrintAnswerToLife()
{
var task = GetAnswerToLife();
int answer = await task;
Console.WriteLine(answer);
}
static async Task<int> GetAnswerToLife()
{
var task = Task.Delay(2000);
await task;
int answer = 21 * 2;
return answer;
}
You can do a pretty straightforward translation of async / await into Task by using ContinueWith. Other translations are also possible, e.g., Task.Delay becomes System.Threading.Timer.
The basic pattern is, for any async method that does an await:
static async Task Go()
{
var task = PrintAnswerToLife();
await task;
Console.WriteLine("Done");
}
becomes:
static Task Go()
{
var tcs = new TaskCompletionSource<object>();
var task = PrintAnswerToLife();
task.ContinueWith(_ =>
{
Console.WriteLine("Done");
tcs.SetResult(null);
});
return tcs.Task;
}
Correct error handling is a lot more work.

Categories