I have a question about how customizable the new async
/await
keywords and the Task
class in C# 4.5 are.
First some background for understanding my problem: I am developing on a framework with the following design:
Update()
function that enumerates the list and look whether some "things" need to execute and does so. Basically its like a big thread sheduler. To simplify things, lets assume the "things to do" are functions that return the boolean true
when they are "finished" (and should not be called next Update) and false
when the sheduler should call them again next update.Update()
- function.An example:
Future f1, f2;
bool SomeThingToDo() // returns true when "finished"
{
if (f1 == null)
f1 = Remote1.CallF1();
else if (f1.IsComplete && f2 == null)
f2 = Remote2.CallF2();
else if (f2 != null && f2.IsComplete)
return true;
return false;
}
Now this all sound awefull like async
and await
of C# 5.0 can help me here. I haven't 100% fully understand what it does under the hood (any good references?), but as I get it from some few talks I've watched, it exactly does what I want with this nicely simple code:
async Task SomeThingToDo() // returning task is completed when this is finished.
{
await Remote1.CallF1();
await Remote2.CallF2();
}
But I can't find a way how write my Update()
function to make something like this happen. async
and await
seem to want to use the Task
- class which in turn seems to need real threads?
My closest "solution" so far:
The first thread (which is running SomeThingToDo
) calls their functions only once and stores the returned task and tests on every Update()
whether the task is completed.
Remote1.CallF1
returns a new Task with an empty Action as constructor parameter and remembers the returned task. When F1 is actually finished, it calls RunSynchronously()
on the task to mark it as completed.
That seems to me like a pervertion of the task system. And beside, it creates shared memory (the Task's IsComplete
boolean) between the two threads which I would like to have replaced with our remote messanging system, if possible.
Finally, it does not solve my problem as it does not work with the await-like SomeThingToDo
implementation above. It seems the auto-generated Task objects returned by an async function are completed immediately?
So finally my questions:
Task<T>
?Task
without anything that relates to "blocking" and "threads"?async
and await
?The async and await keywords don't cause additional threads to be created. Async methods don't require multithreading because an async method doesn't run on its own thread. But in the remarks in description of ThreadPool class ( ThreadPool Class ): Examples of operations that use thread pool threads include the following:
The warning is exactly right: if you mark your method async but don't use await anywhere, then your method won't be asynchronous. If you call it, all the code inside the method will execute synchronously. I want write a method that should run async but don't need use await.for example when use a thread
Show activity on this post. Closed 5 years ago. I am working with async-await and tasks, but I can't understand the one thing: Is async task executes in separate thread? The async and await keywords don't cause additional threads to be created. Async methods don't require multithreading because an async method doesn't run on its own thread.
You should not use async void unless it is an event handler. That is the only acceptable time and is the only correct way of making an async event handler. If your synchronous method is void, it should be async Task.
I haven't 100% fully understand what it does under the hood - any good references?
Back when we were designing the feature Mads, Stephen and I wrote some articles at a variety of different levels for MSDN magazine. The links are here:
http://blogs.msdn.com/b/ericlippert/archive/2011/10/03/async-articles.aspx
Start with my article, then Mads's, then Stephen's.
It seems the auto-generated Task objects returned by an async function are completed immediately?
No, they are completed when the code in the method body returns or throws, same as any other code.
Can I hook into async/await to use my own implementations instead of
Task<T>
?
A method which contains an await
must return void
, Task
or Task<T>
. However, the expression that is awaited can return any type so long as you can call GetAwaiter()
on it. That need not be a Task
.
If that's not possible, can I use Task without anything that relates to "blocking" and "threads"?
Absolutely. A Task
just represents work that will complete in the future. Though that work is typically done on another thread, there is no requirement.
To answer your questions:
Can I hook into async/await to use my own implementations instead of Task?
Yes. You can await anything. However, I do not recommend this.
If that's not possible, can I use Task without anything that relates to "blocking" and "threads"?
The Task
type represents a future. It does not necessarily "run" on a thread; it can represent the completion of a download, or a timer expiring, etc.
Any good reference what exactly happens when I write async and await?
If you mean as far as code transformations go, this blog post has a nice side-by-side. It's not 100% accurate in its details, but it's enough to write a simple custom awaiter.
If you really want to twist async
to do your bidding, Jon Skeet's eduasync series is the best resource. However, I seriously do not recommend you do this in production.
You may find my async
/await
intro helpful as an introduction to the async
concepts and recommended ways to use them. The official MSDN documentation is also unusually good.
I did write the AsyncContext
and AsyncContextThread
classes that may work for your situation; they define a single-threaded context for async
/await
methods. You can queue work (or send messages) to an AsyncContextThread
by using its Factory
property.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With