Why I cannot await object type? - c#

Recently I realized that I can make actually anything awaitable if I implement a GetAwaiter extension method for the type. I know it is completely nonsense but I started to play with that just for fun:
// a minimal awaiter to make the compiler happy
public class MyAwaiter<T> : INotifyCompletion
{
public bool IsCompleted { get; } = true
public T GetResult() => default(T);
public void OnCompleted(Action continuation) { }
}
And the required extension method:
public static class Extensions
{
// await them all!
public static MyAwaiter<T> GetAwaiter<T>(this T obj)
{
return new MyAwaiter<T>();
}
}
Now I can commit this black magic:
private async Task Magic()
{
await "haha!";
await 42;
// await new object(); // <- this line does not compile
}
Awaiting an object fails:
ConfiguredTaskAwaitable<object> does not contain a definition for IsCompleted
I do not understand how ConfiguredTaskAwaitable<object> comes in when I return a MyAwaiter<T> instance. But never mind, second try:
public static MyAwaiter<object> GetAwaiter(this object obj)
{
return new MyAwaiter<object>();
}
Now none of the awaits work:
The call is ambiguous between the following methods or properties: Test.Extensions.GetAwaiter(object) and Test.Extensions.GetAwaiter(object)
This is even more confusing message than the previous one.
If I change the type in the signature to string or int, then I can await strings and integers respectively; however, object does not work. Has someone any clue what in the background happens in case of object?

The only problem I can see is a missing semicolon:
public bool IsCompleted { get; } = true
Your code before your second try (the first 3 pieces of code) including await new object(); compiles on my machine, just like expected. I tried both .NET CORE and .NET framework 4.6 console applications in VS 2017 Community v15.2(26430.6).
Check your code and compiler version again.

Related

Task return type with and without Async [duplicate]

This question already has answers here:
Why use async and return await, when you can return Task<T> directly?
(9 answers)
Closed 5 years ago.
I little bit confused on the behavior of the async keyword.
Lets say I have 2 methods,
public async Task DoSomething1()
{
await Task.Run(() =>
{
for(int i = 0; i<3; i++)
{
Console.WriteLine("I m doing something:" + i);
}
});
}
And
public Task DoSomething2()
{
return Task.Run(() =>
{
for(int i = 0; i<3; i++)
{
Console.WriteLine("I m doing something:" + i);
}
});
}
From my understanding both methods are awaitable. But when I write a method that has a Task return type without the async keyword I need to return a Task otherwise the compiler generates an error. Its a common thing that a method should return its type. But when I use it with the async keyword the compiler generates another error that you can't return a Task. So what does it mean? I am totally confused here.
General Async Info
If you use await in your code, you are required to use the async keyword on the method.
If you use async and want to return an actual type, you can declare that your method returns the type as a generic Task like this Task<int>.
Here are the valid return types for an async method:
https://learn.microsoft.com/en-us/dotnet/csharp/programming-guide/concepts/async/async-return-types
Task<TResult>, for an async method that returns a value.
Task, for an async method that performs an operation but returns no value.
void, for an event handler.
A new answer August 2022
TL;DR - The return type is automatically wrapped in a Task.
I was receiving downvotes on this so I re-read the question in more detail and got to the root of it. It's not about the return type in the signature of the method. Its about the return value. Also it is not a duplicate question!
Anyway, let's look at this method:
public Task TaskMethod()
{
return Task.CompletedTask;
}
This seems pretty normal and what we are used to in C#. You declare the return type and return an object of that type. Easy. (In fact the "lowered" code is the exact same.)
Now for the async case.
public async Task MethodAsync()
{
return Task.CompletedTask;
}
This generates a compile error: error CS1997: Since 'C.MethodAsync()' is an async method that returns 'Task', a return keyword must not be followed by an object expression. Did you intend to return 'Task<T>'?
OK, then we can't return a task directly, let's do the right thing. It is easier to see this example if we return something so, let's return int.
public async Task<int> MethodAsync()
{
return 1;
}
(This method gives a warning that we are using async without await, but ignore this for now.)
The lowered code is complicated, but you can see that a state machine will be generated. The MethodAsync looks like this:
[CompilerGenerated]
private sealed class <MethodAsync>d__0 : IAsyncStateMachine
{
public int <>1__state;
public AsyncTaskMethodBuilder<int> <>t__builder;
public C <>4__this;
private void MoveNext()
{
int num = <>1__state;
int result;
try
{
result = 1;
}
catch (Exception exception)
{
<>1__state = -2;
<>t__builder.SetException(exception);
return;
}
<>1__state = -2;
<>t__builder.SetResult(result);
}
void IAsyncStateMachine.MoveNext()
{
//ILSpy generated this explicit interface implementation from .override directive in MoveNext
this.MoveNext();
}
[DebuggerHidden]
private void SetStateMachine(IAsyncStateMachine stateMachine)
{
}
void IAsyncStateMachine.SetStateMachine(IAsyncStateMachine stateMachine)
{
//ILSpy generated this explicit interface implementation from .override directive in SetStateMachine
this.SetStateMachine(stateMachine);
}
}
[AsyncStateMachine(typeof(<MethodAsync>d__0))]
[DebuggerStepThrough]
public Task<int> MethodAsync()
{
<MethodAsync>d__0 stateMachine = new <MethodAsync>d__0();
stateMachine.<>t__builder = AsyncTaskMethodBuilder<int>.Create();
stateMachine.<>4__this = this;
stateMachine.<>1__state = -1;
stateMachine.<>t__builder.Start(ref stateMachine);
return stateMachine.<>t__builder.Task;
}
And you can see the Task here is automatically returned in the public method. The state machine implements the method body.
You can see that the actual value returned is the int from <>t__builder wrapped in a Task.
To see the lowered code yourself, you can try it in https://sharplab.io.
Also after writing all this I found another answer that explains it in a different way. Guess who wrote that answer?
https://stackoverflow.com/a/37647093/1804678
(...) “async”. This keyword
allows that inside the method the word “await” can be used, and
modifies how its result is handled by the method. That’s it.
The method runs synchronously until it finds the word “await” and that
word is the one that takes care of asynchrony. “Await” is an operator
that receives a parameter: an awaitable (an asynchronous operation)
behaves in this way:
From here

How do i get return value of action running in a thread in C#?

I want to make a function to run stuff in a throw-away thread... aka keep executing stuff without waiting for the function in the line before it to excute.
So i made a little function here...
public static object Do(System.Action Method)
{
object ret;
System.Threading.Thread t = new System.Threading.Thread(() =>
{ret = Method(); });
t.SetApartmentState(System.Threading.ApartmentState.STA);
t.Start();
return ret;
}
Looks simple... there is only one problem... i get the following errors
Cannot implicitly convert type 'void' to 'object'
Use of unassigned local variable 'ret'
I don't care about the second because it will fix itself if i just fix the first... but i don't seem to find a solution for the first...
In short:
All i want is to get the return value of the function chosen aka...
I want the following code to work:
string TEST = Do(() => Console.ReadKey()).ToString();
But the method itself is broken.
Action delegate does not return a value.
Use Func<object> to return object from a passed function.
Also in this case the variable will be most likely returned before the function completes.
I recommend using async/await combination instead. In order for your construction to work you would have do something like this:
public static async Task<object> Do(Func<object> Method)
{
object ret = null;
await Task.Run(
() =>
{
ret = Method();
});
return ret;
}
Which boils down to:
public static async Task<object> Do(Func<object> Method)
{
return Task.Run(Method);
}
Example code:
class Program
{
static AutoResetEvent MyThreadCompletedEvent = new AutoResetEvent(false);
static async void MyThread()
{
Console.WriteLine((await MyClass<ConsoleKeyInfo>.Do(Console.ReadKey)).ToString());
MyThreadCompletedEvent.Set();
}
static void Main(string[] args)
{
Task.Run(() => MyThread());
// Do stuff
// Ensure to wait for MyThread to complete
MyThreadCompletedEvent.WaitOne();
}
}
public static class MyClass<T>
{
public static async Task<object> Do(Func<T> Method)
{
return await Task.Run(Method);
}
}
Instead of creating new thread you could do:
class Program
{
static void Main(string[] args)
{
Console.WriteLine(MyClass<ConsoleKeyInfo>.Do(Console.ReadKey));
}
}
public static class MyClass<T>
{
public static object Do(Func<T> Method)
{
return Method();
}
}
From your title:
How do i get return value of action running in a thread in C#?
You can't. If the thread is still running, the "return value" has not yet been computed. It is not available to return, even if you used the correct Func<T> instead of Action<T>.
In other words, the laws of physics in our universe as we currently know them do not allow for retrieving information from the future.
I want the following code to work:
string TEST = Do(() => Console.ReadKey()).ToString();
Assuming you meant TEST to have the value of the pressed key, then you have to wait for the key to be pressed. The same thing would be obtained with:
string TEST = Console.ReadKey().ToString();
(though you probably would want to use the .KeyChar property...)

How to create a custom class that inherits from Task<T> to use in an async method?

I'm currently updating my solution to match Microsoft All Rules using Visual Studio Code Analysis.
I have an interface which can fetch entities from a database using async, this is done with the following method signature:
Task<IQueryable<TEntity>> EntitiesAsync();
The implementation of this method looks like:
public async Task<IQueryable<TEntity>> EntitiesAsync()
{
DbSet.ThrowIfNull("DbSet");
IQueryable<TEntity> returnList = null;
await Task.Run(() =>
{
if (OnBeforeEntityGetAll != null)
{ OnBeforeEntityGetAll(this, new RepositoryEventArgs(typeof(TEntity))); }
IQueryable<TEntity> query = DbSet;
if (OnEntityGetAll != null)
{ OnEntityGetAll(this, new RepositoryEventArgs(typeof(TEntity))); }
returnList = query.AsQueryable();
});
return returnList;
}
So far so good, this code is working, but the Code Analysis is making some noise saying:
CA1006: Do not nest generic types in member signatures.
This basiclly means that I'm returning nested types, in this case Task<IQuerable<TEntity>>
I tought that I should be able to solve this issue by creating a class that extends this one and that might look like:
public class AsyncQueryResult<TEntity> : Task<IQueryable<TEntity>>
{
public AsyncQueryResult(Func<IQueryable<TEntity>> function)
: base(function)
{ }
}
This does mean that I need to update my method signature to be:
AsyncQueryResult<TEntity> EntitiesAsync();
When I change my implementation method accordingly:
public async AsyncQueryResult<TEntity> EntitiesAsync()
{ }
I do receive a compiler error telling me:
The return type of an async must be Void, Task or Task{T}.
I hope someone does have a clear idea on how I should be able to solve this issue.

How does adding a break in a while loop resolve overload ambiguity?

Consider this Reactive Extensions snippet (ignore the practicality of it):
return Observable.Create<string>(async observable =>
{
while (true)
{
}
});
This does not compile with Reactive Extensions 2.2.5 (using NuGet Rx-Main package). It fails with:
Error 1 The call is ambiguous between the following methods or properties: 'System.Reactive.Linq.Observable.Create<string>(System.Func<System.IObserver<string>,System.Threading.Tasks.Task<System.Action>>)' and 'System.Reactive.Linq.Observable.Create<string>(System.Func<System.IObserver<string>,System.Threading.Tasks.Task>)'
However, adding a break anywhere in the while loop fixes the compilation error:
return Observable.Create<string>(async observable =>
{
while (true)
{
break;
}
});
The problem can be reproduced without Reactive Extensions at all (easier if you want to try it without fiddling with Rx):
class Program
{
static void Main(string[] args)
{
Observable.Create<string>(async blah =>
{
while (true)
{
Console.WriteLine("foo.");
break; //Remove this and the compiler will break
}
});
}
}
public class Observable
{
public static IObservable<TResult> Create<TResult>(Func<IObserver<TResult>, Task> subscribeAsync)
{
throw new Exception("Impl not important.");
}
public static IObservable<TResult> Create<TResult>(Func<IObserver<TResult>, Task<Action>> subscribeAsync)
{
throw new Exception("Impl not important.");
}
}
public interface IObserver<T>
{
}
Ignoring the Reactive Extensions part of it, Why does adding break help the C# compiler resolve the ambiguity? How can this be described with the rules of overload resolution from the C# specification?
I'm using Visual Studio 2013 Update 2 targeting 4.5.1.
It's easiest to just pull out async as well as the lambdas here, as it emphasizes what's going on. Both of these methods are valid and will compile:
public static void Foo()
{
while (true) { }
}
public static Action Foo()
{
while (true) { }
}
However, for these two methods:
public static void Foo()
{
while (true) { break; }
}
public static Action Foo()
{
while (true) { break; }
}
The first compiles, and the second does not. It has a code path that doesn't return a valid value.
In fact, while(true){} (along with throw new Exception();) is an interesting statement in that it is the valid body of a method with any return type.
Since the infinite loop is a suitable candidate for both overloads, and neither overload is "better", it results in an ambiguity error. The non-infinite loop implementation only has one suitable candidate in overload resolution, so it compiles.
Of course, to bring async back into play, it is actually relevant in one way here. For the async methods they both always return something, whether it's a Task or a Task<T>. The "betterness" algorithms for overload resolution will prefer delegates that return a value over void delegates when there is a lambda that could match either, however in your case the two overload both have delegates that return a value, the fact that for async methods returning a Task instead of a Task<T> is the conceptual equivalent of not returning a value isn't incorporated into that betterness algorithm. Because of this the non-async equivalent wouldn't result in an ambiguity error, even though both overloads are applicable.
Of course it's worth noting that writing a program to determine if an arbitrary block of code will ever complete is a famously unsolvable problem, however, while the compiler cannot correctly evaluate whether every single snippet will complete, it can prove, in certain simple cases such as this one, that the code will in fact never complete. Because of this there are ways of writing code that will clearly (to you and me) never complete, but that the compiler will treat as possibly completing.
Leaving async out of this to start with...
With the break, the end of the lambda expression is reachable, therefore the return type of the lambda has to be void.
Without the break, the end of the lambda expression is unreachable, so any return type would be valid. For example, this is fine:
Func<string> foo = () => { while(true); };
whereas this isn't:
Func<string> foo = () => { while(true) { break; } };
So without the break, the lambda expression would be convertible to any delegate type with a single parameter. With the break, the lambda expression is only convertible to a delegate type with a single parameter and a return type of void.
Add the async part and void becomes void or Task, vs void, Task or Task<T> for any T where previously you could have any return type. For example:
// Valid
Func<Task<string>> foo = async () => { while(true); };
// Invalid (it doesn't actually return a string)
Func<Task<string>> foo = async () => { while(true) { break; } };
// Valid
Func<Task> foo = async () => { while(true) { break; } };
// Valid
Action foo = async () => { while(true) { break; } };

How to initialize an object using async-await pattern

I'm trying to follow RAII pattern in my service classes, meaning that when an object is constructed, it is fully initialized. However, I'm facing difficulties with asynchronous APIs. The structure of class in question looks like following
class ServiceProvider : IServiceProvider // Is only used through this interface
{
public int ImportantValue { get; set; }
public event EventHandler ImportantValueUpdated;
public ServiceProvider(IDependency1 dep1, IDependency2 dep2)
{
// IDependency1 provide an input value to calculate ImportantValue
// IDependency2 provide an async algorithm to calculate ImportantValue
}
}
I'm also targeting to get rid of side-effects in ImportantValue getter, to make it thread-safe.
Now users of ServiceProvider will create an instance of it, subscribe to an event of ImportantValue change, and get the initial ImportantValue. And here comes the problem, with the initial value. Since the ImportantValue is calculated asynchronously, the class cannot be fully initialized in constructor. It may be okay to have this value as null initially, but then I need to have some place where it will be calculated first time. A natural place for that could be the ImportantValue's getter, but I'm targeting to make it thread-safe and with no side-effects.
So I'm basically stuck with these contradictions. Could you please help me and offer some alternative? Having value initialized in constructor while nice is not really necessary, but no side-effects and thread-safety of property is mandatory.
Thanks in advance.
EDIT: One more thing to add. I'm using Ninject for instantiation, and as far as I understand, it doesn't support async methods to create a binding. While approach with initiating some Task-based operation in constructor will work, I cannot await its result.
I.e. two next approaches (offered as answers so far) will not compile, since Task is returned, not my object:
Kernel.Bind<IServiceProvider>().ToMethod(async ctx => await ServiceProvider.CreateAsync())
or
Kernel.Bind<IServiceProvider>().ToMethod(async ctx =>
{
var sp = new ServiceProvider();
await sp.InitializeAsync();
})
Simple binding will work, but I'm not awaiting the result of asynchronous initialization started in constructor, as proposed by Stephen Cleary:
Kernel.Bind<IServiceProvider>().To<ServiceProvider>();
... and that's not looking good for me.
I have a blog post that describes several approaches to async construction.
I recommend the asynchronous factory method as described by Reed, but sometimes that's not possible (e.g., dependency injection). In these cases, you can use an asynchronous initialization pattern like this:
public sealed class MyType
{
public MyType()
{
Initialization = InitializeAsync();
}
public Task Initialization { get; private set; }
private async Task InitializeAsync()
{
// Asynchronously initialize this instance.
await Task.Delay(100);
}
}
You can then construct the type normally, but keep in mind that construction only starts the asynchronous initialization. When you need the type to be initialized, your code can do:
await myTypeInstance.Initialization;
Note that if Initialization is already complete, execution (synchronously) continues past the await.
If you do want an actual asynchronous property, I have a blog post for that, too. Your situation sounds like it may benefit from AsyncLazy<T>:
public sealed class MyClass
{
public MyClass()
{
MyProperty = new AsyncLazy<int>(async () =>
{
await Task.Delay(100);
return 13;
});
}
public AsyncLazy<int> MyProperty { get; private set; }
}
One potential option would be to move this to a factory method instead of using a constructor.
Your factory method could then return a Task<ServiceProvider>, which would allow you to perform the initialization asynchronously, but not return the constructed ServiceProvider until ImportantValue has been (asynchronously) computed.
This would allow your users to write code like:
var sp = await ServiceProvider.CreateAsync();
int iv = sp.ImportantValue; // Will be initialized at this point
This is a slight modification to #StephenCleary pattern of async initialization.
The difference being the caller doesn't need to 'remember' to await the InitializationTask, or even know anything about the initializationTask (in fact it is now changed to private).
The way it works is that in every method that uses the initialized data there is an initial call to await _initializationTask. This returns instantly the second time around - because the _initializationTask object itself will have a boolean set (IsCompleted which the 'await' mechanism checks) - so don't worry about it initializing multiple times.
The only catch I'm aware of is you mustn't forget to call it in every method that uses the data.
public sealed class MyType
{
public MyType()
{
_initializationTask = InitializeAsync();
}
private Task _initializationTask;
private async Task InitializeAsync()
{
// Asynchronously initialize this instance.
_customers = await LoadCustomersAsync();
}
public async Task<Customer> LookupCustomer(string name)
{
// Waits to ensure the class has been initialized properly
// The task will only ever run once, triggered initially by the constructor
// If the task failed this will raise an exception
// Note: there are no () since this is not a method call
await _initializationTask;
return _customers[name];
}
// one way of clearing the cache
public void ClearCache()
{
InitializeAsync();
}
// another approach to clearing the cache, will wait until complete
// I don't really see a benefit to this method since any call using the
// data (like LookupCustomer) will await the initialization anyway
public async Task ClearCache2()
{
await InitializeAsync();
}
}
You could use my AsyncContainer IoC container which supports the exact same scenario as you.
It also supports other handy scenarios such as async initializers, run-time conditional factories, depend on async and sync factory functions
//The email service factory is an async method
public static async Task<EmailService> EmailServiceFactory()
{
await Task.Delay(1000);
return new EmailService();
}
class Service
{
//Constructor dependencies will be solved asynchronously:
public Service(IEmailService email)
{
}
}
var container = new Container();
//Register an async factory:
container.Register<IEmailService>(EmailServiceFactory);
//Asynchronous GetInstance:
var service = await container.GetInstanceAsync<Service>();
//Safe synchronous, will fail if the solving path is not fully synchronous:
var service = container.GetInstance<Service>();
I know this is an old question, but it's the first which appears on Google and, quite frankly, the accepted answer is a poor answer. You should never force a delay just so you can use the await operator.
A better approach to an initialization method:
private async Task<bool> InitializeAsync()
{
try{
// Initialize this instance.
}
catch{
// Handle issues
return await Task.FromResult(false);
}
return await Task.FromResult(true);
}
This will use the async framework to initialize your object, but then it will return a boolean value.
Why is this a better approach? First off, you're not forcing a delay in your code which IMHO totally defeats the purpose of using the async framework. Second, it's a good rule of thumb to return something from an async method. This way, you know if your async method actually worked/did what it was supposed to. Returning just Task is the equivalent of returning void on a non-async method.
I have a variation of Stephen Cleary's example of an asynchronous initialization pattern. You could encapsulate the Initialization property and await it in the class methods. In this case, the client code will not need to await the initialization task.
public class ClassWithAsyncInit
{
public ClassWithAsyncInit()
{
Initialization = InitializeAsync();
}
private Task Initialization { get; private set; }
private async Task InitializeAsync()
{
// your async init code
}
public async Task FirstMethod()
{
await Initialization;
// ... other code
}
}
The drawback is that it's not convenient if you have a lot of methods in your class and need to await the Initialization task in each one. But sometimes it is okay. Let's say you have a simple interface for saving some JSON objects:
public IDataSaver
{
void Save(string json);
}
And you need to implement it for a database with the asynchronous initialization logic. Considering that you would have only one public method it makes sense to encapsulate the Initialization property and await it in the Save method:
public class SomeDbDataSaver: IDataSaver
{
protected DatabaseClient DbClient { get; set; }
public SomeDbDataSaver()
{
DbClient = new DatabaseClient();
Initialization = InitializeAsync(); // start off the async init
}
private Task Initialization { get; private set; }
private async Task InitializeAsync()
{
await DbClient.CreateDatabaseIfNotExistsAsync("DatabaseName");
}
public async Task Save(string json)
{
await Initialization;
// ... code for saving a data item to the database
}
}

Categories

Resources