My workflow: Constructor -> Calls async Method 1 -> Calls async Method 2 -> Calls async Method 3
Constructor:
public MyConstructor() {
Method1();
}
Method1:
private async void Method1() {
//do some stuff
await Method2();
//do some more stuff
}
Method 2:
protected internal async Task Method2() {
//do some stuff
var x = await Method3("someParams");
//do some more stuff
}
Method 3:
public async Task<List<string>> Method3(string someParams) {
Debug.WriteLine("I am here"); //Breakpoint doesn't get hit, no output "I am here"
}
Yeah I know, you probably wonder why I am using so many different async methods.. But there is some more stuff going on (but nothing that influences the problem!). The problem is, Debug.WriteLine("I am here"); does not get hit, and no exception is thrown.
What am I doing wrong?
In a nutshell: yes, as #fknx mentioned in a comment, the problem is that the code executes asynchronously and is not awaited, therefore the app exits before reaching the line in question.
There are a couple of bad practices in your example:
async void method
It is not a good idea to create such things as you loose track of the task. Please always define Task as the return value, it does not cost anything and it will help you write a correct API.
asynchronous call in a constructor
This is not a good design either, because (as you mentioned) you cannot await this method in a constructor so you will just fire up the task and loose it. Please consider using an async Init method instead.
So instead of this:
public class MyCustomClass
{
public MyCustomClass()
{
// BAD CODE, do not do this
Method1();
}
private async Task Method1()
{
//do some stuff
await Method2();
//do some more stuff
}
}
You could do this:
class Program
{
static void Main(string[] args)
{
var m = new MyCustomClass();
m.InitializeAsync().Wait();
Console.WriteLine("Before exit...");
}
}
public class MyCustomClass
{
public MyCustomClass()
{
// in a constructor you should not do anything async
}
public async Task InitializeAsync()
{
await Method1();
}
private async Task Method1()
{
//do some stuff
await Method2();
//do some more stuff
}
}
It is absolutely OK to Wait for an async method in the Main method, or to be precise your console app should have only one Wait (or WaitAll, or whatever) method in the main method (and nowhere else) if you want to create a truly async app.
Related
This question already has answers here:
Can constructors be async?
(15 answers)
Async method which is called from constructor [duplicate]
(2 answers)
c# start async method within object constructor - bad practice? [closed]
(6 answers)
Closed 2 years ago.
I've been trying to find a design for the situation where you have a type that has a dependency and you want to call a method that returns a Task. The gut reaction is to do GetAwaiter().GetResult() but I know that goes against the whole purpose of asynchronous tasks. The thought is to spin up the task but let it do its thing until the type needs it.
public class SomeClass {
private readonly Task<Data> _getDataTask;
private readonly IDependency _dep;
private Data _data;
public SomeClass(IDependency dep) {
_dep = dep;
// I'll spin this up but I don't need the result yet
_getDataTask = _dep.GetDataAsync();
}
public async Task DoSomeWork() {
// Now I need the result of the task so I'll await the task
_data = await _getDataTask;
ExecuteWorkOn(_data);
}
}
Maybe this approach would produce a lot of condition statements to await if you don't have the result cached? I'm hoping to get feedback on this approach in the hopes that either another SO question gets linked or we come up with a design we didn't think about before.
UPDATE 1
I made the Task to be Task<Data> as mentioned in one of the comments
There are two good solutions for this problem:
First:
Use a async init methode in the constructor and hold the resulting Task in a property. This way the calling code can await the completion if the initilisation.
public class Foo
{
public Task InitTask { get; private set; }
public Foo()
{
this.InitTask = this.Init();
}
private async Task Init() { ... }
}
can be used like this
var newFoo = new Foo();
await newFoo.InitTask();
// can now use newFoo
Second:
Use a use only private constructors and have a Create methode which you use to create intances for your class
public class Foo
{
public Foo() { }
public async Task<Foo> Create()
{
var newFoo = new Foo();
await newFoo.Init();
return newFoo;
}
private async Task Init() { ... }
}
can be used like this
var newFoo = await Foo.Create();
Your approch, if not bad, is a variant of approch 1 but would mean that you need to await the task started in the constructor in every methode that needs the result (or side effect) of the task.
public class Foo
{
private Task InitTask { get; private set; }
public Foo()
{
this.InitTask = this.Init();
}
private async Task Init() { ... }
public async Task DoStuffA()
{
await this.InitTask;
// do work
}
public async Task DoStuffB()
{
await this.InitTask;
// do work
}
public async Task DoStuffC()
{
await this.InitTask;
// do work that could be done without async/await
}
}
So I would recommend approch 2 to do async initialization.
Let's say I have 100s of classes that implement a common interface with a method "calculate". Some of the classes will execute async (e.g. read a file), and other classes implementing the same interface will execute code that is sync (e.g. adding two numbers). What is a good way to code this, for maintenance and for performance?
The posts I read so far, always recommend to make async/await methods bubble up to the callers. So if you have one operation that is async, make the caller async, then its caller async, and so on. So this makes me think that the interface should be an async interface. However, this creates a problem when implementing the interface with code that is synchronous.
One idea I thought of is to expose in the interface 2 methods, one async and one sync, and one boolean property to tell the caller which method to call. This would look really ugly though.
The code I currently have is only one interface method that is async. Then for implementations that are synchronous, they wrap the code inside a Task object:
using System.IO;
using System.Threading.Tasks;
namespace TestApp
{
interface IBlackBox
{
Task<string> PullText();
}
sealed class MyAsyncBlackBox : IBlackBox
{
public async Task<string> PullText()
{
using (var reader = File.OpenText("Words.txt"))
{
return await reader.ReadToEndAsync();
}
}
}
sealed class MyCachedBlackBox : IBlackBox
{
public Task<string> PullText()
{
return Task.Run(() => "hello world");
}
}
}
Is this the right approach to create and implement an interface that is only sometimes async? I have a lot of classes that implement short synchronous operations, and worry that this could add a lot of overhead. Is there some other way to do this that I am missing?
This is a common situation with interfaces. If you have a contract that needs to specify a task for the Async Await Pattern and we have to implement that Task in the interface.
Assuming the caller is going to use await you can just drop the async and return a Task.
However, you need to be-careful with your exceptions. It's assumed that exceptions are placed on the task. So to keep this plumbing the caller will expect you have to handle them slightly differently.
Common usages
Standard async
public async Task<string> PullText()
{
using (var reader = File.OpenText("Words.txt"))
{
return await reader.ReadToEndAsync();
}
}
Returning a Task for CPU bound work (capturing the exception and placing it on the Task)
public Task<string> PullText()
{
try
{
return Task.Run(() => DoCpuWork());
}
catch (Exception e)
{
return Task.FromException<string>(e);
}
}
Slightly less efficient as we are plumbing an IAsyncStateMachine
public async Task<string> PullText()
{
return await Task.Run(() => DoCpuWork());
}
Returning a completed Task with a simple results (capturing the exception and placing it on the Task)
public Task<string> PullText()
{
try
{
// simplified example
return Task.FromResult("someString");
}
catch (Exception e)
{
return Task.FromException<string>(e);
}
}
There is also a 3rd approach, you can use the async keyword, and pragma out the warnings, this takes care of the error semantics for you. This feels a little dirty to me, just because it looks messy and the need to pragma out the warning, though I have now seen this used in bespoke production libraries
#pragma warning disable 1998
public async Task<string> PullText()()
#pragma warning restore 1998
{
return Task.Run(() => "hello world");
}
and
#pragma warning disable 1998
public async Task<string> PullText()()
#pragma warning restore 1998
{
return Task.FromResult("someString");
}
Note all the above deal with returning a Task<T> from the method. If one was just wanting to return the Task you can take advantage of Task.CompletedTask; with the same error semantics as above.
Usually in these cases, You have something in front of the call that is handling the request and passing it off to the "worker" classes (e.g. TestApp). If this is the case, I don't see why having an "IAsyncable" interface where you could test if the class was async capable would not work.
if(thisObject is IAscyncAble) {
... call the ansync request.
}
I ended up using the following code:
using System.IO;
using System.Threading.Tasks;
namespace TestApp
{
interface IBlackBox // interface for both sync and async execution
{
Task<string> PullText();
}
sealed class MyAsyncBlackBox : IBlackBox
{
public async Task<string> PullText()
{
using (var reader = File.OpenText("Words.txt"))
{
return await reader.ReadToEndAsync();
}
}
}
sealed class MyCachedBlackBox : IBlackBox
{
public Task<string> PullText() // notice no 'async' keyword
{
return Task.FromResult("hello world");
}
}
}
Suppose I have various arbitrary sections of code to run, but before each section, I have to run a Start() method and then after each section I need to run a Complete() method. However, if an exception is thrown in the code section, I want to run a Fail(string message) method instead of Complete(). Is there a design pattern that elegantly encapsulates this to make it neat and easily repeatable?
For example, let's say I have a type called Thing that contains a Start() method that adds a row to a logging db table to reflect that a task is in progress, a Complete() method that changes that row to reflect that the task finished and a Fail(string message) method that changes the row to reflect that the task failed. These are just examples though, they could be doing any set-up and tidy up type tasks.
The naive implementation might be simply to call those methods manually:
public void DoStuff()
{
var thing = new Thing();
thing.Start();
try
{
DoImportantStuff();
thing.Complete();
}
catch (Exception e)
{
thing.Fail(e.Message);
}
}
But if I'm going to have to repeat this in a lot of different places, it ends up creating quite a lot of duplication and it might be easy to forget to call Complete or mess this up in some subtle way.
In C#, there's the using pattern, which provides a good way of encapsulating most of this. For example, if my Thing type looked like this:
public class Thing : IDisposable
{
public Thing(){
Start();
}
private void Start() { /* start */ }
private void Complete() { /* complete */ }
public void Dispose()
{
Complete();
}
}
My DoStuff() method could now be simplified to this:
public void DoStuff()
{
using(new Thing())
{
DoImportantStuff();
}
}
Which is much nicer. But it doesn't allow me to call Fail instead of Complete if an exception is thrown because (I think!) the Dispose method is essentially called in a Finally block.
I have thought of having a try/catch inside the using block and then setting a thing.HasFailed flag inside the catch block and then using that in the Dispose method to decide whether to Complete or Fail. But that seems a bit fiddly and I'd like the consumer of Thing to have to do as little as possible to make it work correctly.
So is there a design pattern that encapsulates what I want to do and avoids the need to manually write a try\catch each time?
You could have a Thing like this:
public class Thing
{
private void Start() { /* start */ }
private void Complete() { /* complete */ }
private void Fail(string message) {}
public void DoAction(Action action)
{
this.Start();
try
{
action();
this.Complete();
}
catch (Exception e)
{
this.Fail(e.Message);
}
}
}
And Use it like this:
Thing thing = new Thing();
thing.DoAction(this.DoStuff);
The pattern is called "template method". You can find your implementation under the title "aspect oriented programming".
(https://msdn.microsoft.com/en-us/library/aa288717(v=vs.71).aspx)
Using Delegates.
public class Thing : IDisposable
{
private void Start() { /* start */ }
private void Complete() { /* complete */ }
private void Fail(string _szMessage) {/* fail */}
public delegate void ProcessClientStuff();
private ProcessClientStuff m_delegateClientStuff;
public Thing(ProcessClientStuff _delegateClientStuff) {m_delegateClientStuff = _delegateClientStuff}
public void Dostuff()
{
Start();
try
{
m_delegateClientStuff();
Complete();
}
catch(Exception e)
{
Fail(e.Message);
}
}
}
void ClientStuff()
{
Console.WriteLine("Hello");
}
Thing oClientStuffProcessor = new Thing(ClientStuff);
oClientStuffProcessor.Dostuff();
We have a generic Job class which have an abstract HeavyTask method like this:
abstract class Job {
private Task m_task;
protected abstract void HeavyTask();
public void StartJob(){
m_task = Task.Run(() => HeavyTask());
}
public async Task WaitJob(){
await m_task;
}
}
And the derived class override the HeavyTask function and also make it async:
class JobFoo : Job {
protected override async void HeavyTask()
{
await Task.Delay(1000);
Debug.WriteLine("JobFoo is done");
}
}
Then when we are using this method, it seems that the HeavyTask() is not awaited:
Job job = new JobFoo();
job.StartJob();
await job.WaitJob();
Debug.WriteLine("All Done");
Output:
All Done
JobFoo is Done
If we don't have async for the override HeavyTask, then it is working as expected. But I cannot guarantee those whose override the Job won't make the HeavyTask async. I want to understand why it is not awaited successfully and is there a way to make sure it will awaited? If you can, could you also explain whether it is a good practice to override a non-async function as async as shown above?
It's not awaited because there's no awaitable (i.e. Task) to await. That method has a void return type. And you should avoid using async void outside of event handlers.
If you want to enable a derived class to use async have the method return a Task to begin with:
protected abstract Task HeavyTaskAsync();
And if you then need to have a synchronous override return a Task synchronously:
override Task HeavyTaskAsync()
{
// do stuff;
return Task.CompletedTask;
}
I don't think this line is awaitable:
m_task = Task.Run(() => HeavyTask());
What is it spouse to wait for? No value is returned.
how about
Task.Run(() => HeavyTask()).Wait();
If I have an interface such as:
using System.Threading.Tasks;
...
public interface IFoo
{
Task doIt();
Task<bool> doItAndReturnStuff();
}
and one of the classes implementing this interface just happens to not require async methods, how can i correct override these functions?
In other words, how do I correctly return "void" and "bool" wrapped in Task objects?
For example:
public class FooHappensToNotNeedAsync : IFoo
{
public override Task doIt()
{
// If I don't return anything here, I get
// error that not all code paths return a value.
// Can I just return null?
}
public override Task<bool> doItAndReturnStuff()
{
// If I want to return true, how to I do it?
// This doesn't work:
return true;
}
}
NOTE - I can't strip the Task stuff completely because some of the classes that implement this interface are in fact asynch.
Thanks
It's not clear what you're trying to achieve, but one approach (which would look the most like "normal" code) is probably just to make them async methods anyway:
public async Task DoIt()
{
// No-op
}
public async Task<bool> DoItAndReturnStuff()
{
return true;
}
Without any await expressions, the method will complete synchronously anyway. You'll get a warning on each method, but you could disable that just for this piece of code using a #pragma.
Alternatively - and I guess more simply in terms of not requiring a #pragma to disable warnings - would be to use Task.FromResult:
public Task DoIt()
{
// Returns a Task<bool>, but that's okay - it's still a Task
return Task.FromResult(true);
}
public Task<bool> DoItAndReturnStuff()
{
return Task.FromResult(true);
}