Calling an async method from a non-async method - c#

Every variation on the following code that I try doesn't work - whether DoSomething() : void and is called as written, or DoSomething() : Task and is called with TaskEx.RunEx(), some attempt involving .GetAwaiter().GetResult(). Errors seen include: "Start may not be called on a task with null action", "RunSynchronously may not be called on a task unbound to a delegate", and "The task has not yet completed".
class Program
{
static void Main(string[] args) // Starting from a non-async method
{
DoSomething();
Console.WriteLine("Press any key to quit.");
Console.ReadKey();
}
static async void DoSomething()
{
Console.WriteLine("Starting DoSomething ...");
var x = await PrepareAwaitable(1);
Console.WriteLine("::" + x);
var y = await PrepareAwaitable(2);
Console.WriteLine("::" + y);
}
static Task<string> PrepareAwaitable(int id)
{
return new Task<string>(() =>
{
return "Howdy " + id.ToString();
});
}
}
Output:
Starting DoSomething ...
Press any key to quit.
PrepareAwaitable's Task's Action will be more complicated later. When this action completes, however long that takes, I would expect the Task (or other Framework mechanisms) to resume by assigning "Howdy ..." to x, and then later to y. What I REALLY want to do is intercept the awaited objects, process them, and at some later time that I control, resume to the continuation with a result (x and y). But I haven't been getting very far on that big step, so I'm trying to start smaller.

First, read the Task-Based Asynchronous Pattern document. It's under My Documents\Microsoft Visual Studio Async CTP\Documentation. This document describes how to design APIs naturally consumable by await.
Secondly, realize that there are several aspects of the Task class and related APIs that no longer really apply in the new asynchronous world. Task was originally written as the core of TPL. It turned out to be a good fit for asynchronous programming, so Microsoft used it instead of creating a new "Promise" class. But a number of methods are holdovers, used by TPL but not needed for async programming.
To answer the titular question, mixing synchronous and asynchronous code is not quite straightforward with the current async CTP. I've written a library that includes a Task.WaitAndUnwrapException extension method, which makes it easy to call async code from sync code. You may also be interested in my AsyncContext class, which makes the "press any key" prompt unnecessary.

The tasks you returned haven't started yet (i.e., they're "cold" tasks); try replacing the PrepareAwaitable code with the following:
static Task<string> PrepareAwaitable(int x)
{
return Task.Factory.StartNew<string>(() =>
{
return "Howdy " + x.ToString();
});
}

It's really not clear what you're trying to achieve, because there's nothing asynchronous going on. For example, this will compile and run, but I don't know whether it's what you want:
using System;
using System.Threading.Tasks;
class Program
{
static void Main(string[] args)
{
DoSomething();
Console.WriteLine("Press any key to quit.");
Console.ReadKey();
}
static async void DoSomething()
{
Console.WriteLine("Starting DoSomething ...");
var x = await PrepareAwaitable(1);
Console.WriteLine("::" + x);
var y = await PrepareAwaitable(2);
Console.WriteLine("::" + y);
}
static async Task<string> PrepareAwaitable(int x)
{
return "Howdy " + x;
}
}
Note that this gives a warning for PrepareAwaitable because there's nothing asynchronous in it; no "await" expressions. The whole program executes synchronously. Another alternative implementation of PrepareAwaitable:
static Task<string> PrepareAwaitable(int x)
{
return TaskEx.Run(() => "Howdy " + x);
}
Is that more like what you were after?

add GetAwaiter().GetResult() after your async task should work. But for eliminating errore like "...not be called on a task with null action", you simply have your Task<IHttpActionResult> to return Ok(true) rather than Ok().
It fixed the GetResult() issue for me !

Related

async await code executing not as expected

I created a simple example to understand async/await in C#.
class Program
{
static void Main(string[] args)
{
var t = BarAsync();
Console.WriteLine("Main");
}
private static async Task BarAsync()
{
Console.WriteLine("This happens before await");
int i = await QuxAsync();
Console.WriteLine("This happens after await. This result of await is " + i);
}
private static Task<int> QuxAsync()
{
int c = 0;
for (int i = 0; i < int.MaxValue; i++)
{
c++;
}
Console.WriteLine("in the middle processing...");
return Task.FromResult(c);
}
}
So the program prints This happens before await first then count the value from a return method. Afterwards it prints the result.
It looks good. My question is that since await doesn't block the thread that evaluates the async method. My understanding is if the async takes a long time it will return to its calling method.
For my example, because QuxAsync() takes a long time, the code
Console.WriteLine("Main");
is not blocked and will be evaluated very soon.
I think the print order should be
This happens before await
Main
in the middle processing...
This happens after await. This result of await is 2147483647
However it is not, why?
I'll second (third?) others' recommendations that you continue reading and learning about async. I'm partial to my own async intro, but these days there are a number of good ones out there.
My question is that since await doesn't block the thread that evaluates the async method. My understanding is if the async takes a long time it will return to its calling method.
This is the part that is wrong. Asynchrony has absolutely nothing to do with how long something takes.
There's two pieces of knowledge missing, both covered in my async intro.
First: await works by first checking its argument. If it is already completed, then await continues executing - synchronously.
Second: every method is called synchronously. Including async methods. The only time asynchrony happens is when an async method has an await whose argument is not already completed; in that case, that async method returns an incomplete task.
Putting both of these together should explain why your code actually runs synchronously.

C# async/await await doesn't await

I am using .Net 4.7.2 and C# 7
In a class there are serveral methods, all void. Some of them can be executed asynchronously, others have to be executed sequentially. So I defined a list for the parallels
private void ExecuteSequential()
{
SomeMethod1();
SomeMethod2();
ExecuteParallelAsync();
SomeMethod3();
SomeMethod4();
}
private async void ExecuteParallelAsync()
{
List<Action> methods = new List<Action>()
{
MyMethod1,
MyMethod2,
MyMethod3
};
await Task.Run( () => { Parallel.ForEach( methods , ( currentMethod ) => currentMethod.Invoke() ); } );
}
Before SomeMethod3 happens to be executed ExecuteParallelAsync should be finished entirely.
Because that's not the case, apparently something is wrong with my usage of async and await.
What I am doing wrong?
Thanks in advance!
async void - all bets are off; in reality, you should never write an async void method unless you're in the tiny tiny set of extreme corner cases that require it, such as async event-handlers.
Before SomeMethod3 happens to be executed ExecuteParallelAsync should be finished entirely.
how could it possibly know? it is: async void, which means it doesn't give anything to the caller that indicates the state.
To do that, it must be:
private async Task ExecuteParallelAsync() // or ValueTask
and you must await it at the call site
await ExecuteParallelAsync();
Marc's answer is the correct solution, but I wanted to explain more about why.
A very key thing to understand about async methods is that:
They start synchronously.
When the await keyword is used, and await given an incomplete Task, the method returns - yes, even if you're only halfway through your method. The magic is in what it returns.
So lets look at what your code does:
Call ExecuteParallelAsync().
ExecuteParallelAsync() starts running synchronously.
Task.Run returns a Task object that is not complete yet.
The await keyword inspects the Task, sees that it is not complete, so it creates a new Task, signs up the rest of the method as a continuation of that Task (there is nothing left to do in this case, but it still happens) and returns.
Because the return type is void it cannot return a Task. But it still returns!
So all that means that ExecuteParallelAsync() returns before the Task.Run is completed, and ExecuteSequential() has no way to tell when the work is actually complete.
This is commonly called "fire and forget" (i.e. "go do this and I don't care when or if you finish").
As Marc's answer points out, if you want to know when it's done, you need to return a Task, which you can then await to know when it's done.
Microsoft has very well written articles about asynchronous programming that you may benefit from reading: Asynchronous programming with async and await
If you want an implementation without async/await sugar keyword:
private void ExecuteParallelAsync()
{
List<Action> methods = new List<Action>()
{
MyMethod1,
MyMethod2,
MyMethod3
};
Task.WaitAll(methods.Select((action) => Task.Run(action)).ToArray())
}
Step 1, reproduce
public void Method()
{
SomeMethod();
SomeMethod();
ExecuteParallelAsync(); //< ---fire and forget
SomeMethod();
SomeMethod();
Console.ReadLine();
}
private void SomeMethod() => Console.WriteLine($"SomeMethod");
private async void ExecuteParallelAsync()
{
Console.WriteLine($"START");
await Task.Delay(TimeSpan.FromMilliseconds(100));
Console.WriteLine($"END");
}
Output
SomeMethod
SomeMethod
START
SomeMethod
SomeMethod
END
Step 2, trying to fix
"Oh yes, I forgot to await my function"
await ExecuteParallelAsync(); //Change 1. "I forgot to await"
Output
Compilation error (line 12, col 3): The 'await' operator can only be used within an async method. Consider marking this method with the 'async' modifier and changing its return type to 'Task'.
Compilation error (line 12, col 3): Cannot await 'void'
Step 3, fix
Addressing both errors from step 2.
// Change 2
// was:public void Main()
// which caused: "The 'await' operator can only (...)"
public async Task Main()
(...)
// Change 3
// was: private async void ExecuteParallelAsync()
// which caused "Compilation error (line 12, col 3): Cannot await 'void'"
private async Task ExecuteParallelAsync()
Run.
Output:
SomeMethod
SomeMethod
START
END
SomeMethod
SomeMethod
For reference, we could have waited for ExecuteParallelAsync without the await keyword, but await is the correct way in all scenarios except the tiny minority where it's not.
a small complete example:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
namespace test
{
class Program
{
static void Main(string[] args)
{
SomeMethod1();
ExecuteParallelAsync();
SomeMethod2();
Console.ReadKey();
}
static void SomeMethod1()
{
Console.WriteLine("SomeMethod1");
}
static void SomeMethod2()
{
Console.WriteLine("SomeMethod2");
}
static void ExecuteParallelAsync()
{
Console.WriteLine("\tstart of ExecuteParallelAsync");
var rd = new Random();
List<Action> methods = new List<Action>()
{
()=>{Thread.Sleep((int) Math.Ceiling(rd.NextDouble()*1000));Console.WriteLine("MyMethod1"); },
()=>{Thread.Sleep((int) Math.Ceiling(rd.NextDouble()*1000));Console.WriteLine("MyMethod2"); },
()=>{Thread.Sleep((int) Math.Ceiling(rd.NextDouble()*1000));Console.WriteLine("MyMethod3"); },
};
Task.WaitAll(methods.Select((action) => Task.Run(action)).ToArray());
Console.WriteLine("\tend of ExecuteParallelAsync");
}
}
}
example of a result:
SomeMethod1
start of ExecuteParallelAsync
MyMethod2
MyMethod3
MyMethod1
end of ExecuteParallelAsync
SomeMethod2

How to chain synchronous and aynchronous methods correctly together in CSharpFunctionalExtensions?

I am familiarizing with CSharpFunctionalExtensions. There are clear examples of synchronous usage and asynchronous usage. However, in some situations these needs to be chained together (sync and async combined). Am I doing this correctly by using Task.FromResult in my Main method? Or should I call a different functional extension method? For this situation, it works and the application outputs the expected 8 but that does not mean that this is the best approach I can use in all my software applications.
class Program
{
// Assume this is a normal synchronous operation
static Result<int> GetMyLength(string text) => Result.Ok(text.Length);
// Assume this a typical async operation, such as a web request
static async Task<Result<int>> DuplicateThisAsync(int x) => await Task.FromResult(Result.Ok(x * 2));
static async Task Main()
{
var tryResult = await Task.FromResult(GetMyLength("Daan"))
.OnSuccess(a => DuplicateThisAsync(a));
Console.WriteLine(tryResult.Value);
Console.ReadLine();
}
}
You don't need to await on Synchronous operation
class Program
{
// Assume this is a normal synchronous operation
static Result<int> GetMyLength(string text) => Result.Ok(text.Length);
// Assume this a typical async operation, such as a web request
static async Task<Result<int>> DuplicateThisAsync(int x) => await Task.FromResult(Result.Ok(x * 2));
static async Task Main()
{
var tryResult = GetMyLength("Daan")
if tryResult.Success // Something similar if .Success is not available
{
tryResult = await DuplicateThisAsync(tryResult.Value));
Console.WriteLine(tryResult.Value);
}
Console.ReadLine();
}
}

C# Async, why we need to "hold" the console to get the async result?

For the past several days, I've been trying to figure out why my async method is not working and its a very simple piece of code.
public class EntryPoint
{
static void Main()
{
RunTheTaskAsync();
//Console.ReadLine(); // if I add this to "hold" the finish of the project, I will see the result, without it I dont
}
public async static void RunTheTaskAsync()
{
Task<string> task = Concatenator('1', 200000);
Console.WriteLine("Heeeelllooooooo");
Console.WriteLine("I am running while Concatenator is concatenating in the background.");
Console.WriteLine("You will receive the results shortly");
string result = await task;
Console.WriteLine("Result is: " + result.Length);
}
public static Task<string> Concatenator(char characterToConcatenate, int count)
{
Console.WriteLine("Concatenating!");
return Task<string>.Factory.StartNew(() =>
{
string concatenatedString = "";
for (int i = 0; i < count; i++)
{
concatenatedString += characterToConcatenate;
}
return concatenatedString;
});
}
}
If I run it as it is in the example above, I never get to see the result, I only see the Console.WriteLine's and Press any key to continue.. after that no result.
If I uncomment the Console.ReadLine(); everything works as I am expecting it to work and I simply cant understand why!?! The same is true if I add some Thread.Sleep(xxx) or another piece of code that will take longer to execute than the "Concatenator" method.
Isn't this one of the issues that await should solve on its own, its kind of implied from its very name.
The way I understand it is:
The Task method starts executing on the background
We proceed with the 3 ConsoleWritelines in the async method
Since there is nothing else to do and the task is not completed yet, we get to the await line and we should await for the task
to be completed and then proceed with the rest of the code.
It works like this ONLY if have another piece of code inbetween that will take longer than the Task method to execute, or if I use the Console.ReadLine() and I just cant find an explanation about this!
I also have a secondary question regarding the syntax of my implementation. Is this the proper way to create a Task method? By using
public Task<T> SomeMethodName(some, args)
{
return Task<T>Factory.StartNew(() =>
{
somecode that returns T;
});
}
async voids (like your RunTheTaskAsync method) are "fire and forget". You can't track their progress and almost never want to use them.
Instead, make an async Task and await it:
static async Task Main()
{
await RunTheTaskAsync();
}
public static async Task RunTheTaskAsync()
{
...
}
For more details, see:
Async/Await - Best Practices in Asynchronous Programming
Note: Visual Studio prior to 2017 Update 3 does not support an async Main method. In that case, you have to manually await the Task:
static void Main()
{
RunTheTaskAsync().GetAwaiter().Wait();
}
About your second question (for the future: SO's policy is "one question per question"): Yes, Task.Factory.StartNew is correct if you need your task to run in a separate thread. Newer versions of .NET as offer Task.Run as a shortcut, see the following question for details:
What is the difference between Task.Run() and Task.Factory.StartNew()

asynchronous Programming in C#

Recently I try to learn about the new C# feature, async/await keywords for asynchronous programming. When I searched at web, I faced this example:
static void Main(string[] args)
{
Console.WriteLine("Task based APM demo");
// Call Exponnent() asynchronously.
// And immediately return the control flow.
// If I don't put a Task here, the program will sometimes
// terminate immediately.
Task t = new Task(async () =>
{
int result = await Program.Exponent(10);
// After the operation is completed, the control flow will go here.
Console.WriteLine(result);
});
t.Start();
Console.ReadKey();
}
static async Task<int> Exponent(int n)
{
Console.WriteLine("Task started");
return await TaskEx.Run<int>(() => 2 << (n - 1));
}
}
I have questions about it and about the manner that this statements act.
First as I understand an await expression used when we want release the process at that point and return to the caller context. But why this expression used this at the line which the Exponent method called at it? In fact what happen when the compiler faced this line of program?
And the letter question is, why the program use "TaskEx.Run" for returning the result in the body of Exponent method? Is it possible to use "return await (() => 2 << (n - 1));" only? How the compiler behaves with this line?
Thanks in advance
But why this expression used this at the line which the Exponent called at it?
I'm not sure what you mean by this question. await Task.Run<int>(() => 2 << (n - 1)); tells the compiler to suspend execution of the current method until the task completes. In terms of task, this is similar to:
Task.Run<int>(() => 2 << (n - 1)).ContinueWith(t=>return t.Result);
But, of course, you cannot return from a continuation. The async keyword tells the compiler not only that there could be one or more await operators in the method, but set's up a state machine to manage the different state transitions starting and returning from asynchronous operations. As well, this could affect how the method is executed in relationship to being asynchronous to the caller.
As to the Task used in Main: you can't await a method call in Main, so, I assume the Task is used to still use the await operator. But, it seems redundant. I would probably simply have another method to use await:
static async void Method()
{
Console.WriteLine(await Exponent(10));
}
Then re-write Main:
static void Main(string[] args)
{
Method();
Console.ReadLine();
}
But, I don't know the reasons behind why the code was originally written that way or even if there was a real purpose.
Is it possible to use "return await (() => 2 << (n - 1));"
It is not possible to write this line of code because nothing asynchronous is being performed. () => 2 << (n - 1) neither returns a Task object not has an GetAwaiter method associated with it; so, it can be executed asynchronously. thus, it can't be "awaited".

Categories