According to an article in MSDN Magazine, it is the best practice to "Use ConfigureAwait(false) when you can." Furthermore it states, "If you can use ConfigureAwait at some point within a method, then I recommend you use it for every await in that method after that point." Stephen Cleary, the author of that article, states on his blog that "In your 'library' async methods, use ConfigureAwait(false) wherever possible [emphasis added]."
Given that most or all of my await statements in a library project that is meant to be widely used should have .ConfigureAwait(false) is it possible to do something/change a setting to make it so that the default behavior of await within my project/dll is to not continue on the a captured context? That is, so that I could omit all the calls to .ConfigureAwait(false) and instead add .ConfigureAwait(true) only when I need the context to be preserved.
No, there is no option for this. The Microsoft team did consider a compiler setting or something for that behavior, but ended up rejecting it.
The main reason is that it's quite difficult to tell how the code behaves without knowing how the compiler switch is set.
There is now a third party library that supports this. The ConfigureAwait.Fody Nuget package allows you to use a ConfigureAwait attribute to mark a class, assembly or method such that all awaits should be .ConfigureAwait(false). The project page has this example usage:
using Fody;
[ConfigureAwait(false)]
public class MyAsyncLibrary
{
public async Task MyMethodAsync()
{
await Task.Delay(10);
await Task.Delay(20);
}
public async Task AnotherMethodAsync()
{
await Task.Delay(30);
}
}
I have not tried this myself, but given what I know about how Fody add-ins work, it is certainly possible.
Related
We have an old library written in C# targeting framework 2.0. Recently we are going to use it in a modern .net core project and intend to use async/await. However, the old library has a lot of lock blocks.
We plan to add new async methods to implement the same logic.
For example,
the old code
void GetOrder()
{
// ...
lock(_lock)
{
//...
}
}
expected result
async Task AsyncGetOrder()
{
// ...
await DoSomethingWithLock()
}
Please give me some advices about how to translate lock into async/await.
You could use SemaphoreSlim, but if there's a lot of it, the AsyncLock library will probably make the conversion much easier (and cleaner).
Just go with the AsyncLock library and relax.
The first thing you need to take into account is that async methods can call non-async methods, but it's not trivial for non-async methods to call async methods and wait for them to finish.
This means that every method that has a lock inside of it will probably need to be called only by async methods. You can do blocking waits for async methods but then there's no point to refactoring and you have to be very careful to avoid deadlocks.
You also need to be aware that in some project types there's an importance to the identity of the executing thread. For example in WPF there are some things that only the UI thread is allowed to do, and if you launch a Task that runs such code from a thread in the thread-pool, you're likely to experience exceptions.
Having said that, if you want to refactor a method that waits on a lock into an async method that asynchronously waits for a lock/semaphore, you should use SemaphoreSlim and await the WaitAsync call. This way the async method will yield control when the SemaphoreSlim is blocking execution, and resume execution at some point later.
There are a few general approaches:
#1 Refactor away from the need for locks at all
Look around for how to write lock-free C#. Sometimes it involved judicious use of the Interlocked class. Other times it involves a shift in mindset toward immutable state (ask a functional programmer). There are many cases when doing this has boosted parallel performance significantly.
And of course lockless threadsafe code can be executed either synchronously or asynchronously.
#2 Refactor away from the need for a reentrant lock, then go async with something that doesn't allow reentrance
This is basically what people are recommending when they recommend SemaphoreSlim, the AsyncEx NuGet package, or similar.
Stephen Cleary has written about the wisdom behind going this route. He also gives some examples of how to do it:
https://blog.stephencleary.com/2013/04/recursive-re-entrant-locks.html
#3 Find an async drop-in replacement for Monitor.Lock/lock
Basically what you need is something that gives all three of these at the same time:
Asynchronicity
Reentrance
Mutual exclusion
Monitor.Lock/lock give you the second and third things. So you want something that gives you the first one also without sacrificing the other two.
This is a little trickier than it might seem. At first glance there are several NuGet packages which appear to do this. But the only correct one that I know of is this NuGet package (which I wrote):
https://www.nuget.org/packages/ReentrantAsyncLock/
Here it is in action:
var asyncLock = new ReentrantAsyncLock();
var raceCondition = 0;
// You can acquire the lock asynchronously
await using (await asyncLock.LockAsync(CancellationToken.None))
{
await Task.WhenAll(
Task.Run(async () =>
{
// The lock is reentrant
await using (await asyncLock.LockAsync(CancellationToken.None))
{
// The lock provides mutual exclusion
raceCondition++;
}
}),
Task.Run(async () =>
{
await using (await asyncLock.LockAsync(CancellationToken.None))
{
raceCondition++;
}
})
);
}
Assert.Equal(2, raceCondition);
This is certainly not the first attempt at doing this. But like I said it's the only correct attempt that I've seen so far. Some other implementations will deadlock trying to re-enter the lock in one of the
Task.Run calls. Others will not actually provide mutual exclusion and the
raceCondition variable will sometimes equal 1 instead of 2:
Stephen Cleary's POC does not provide mutual exclusion: https://dotnetfiddle.net/vLKyCX
NeoSmart.AsyncLock does not provide reentrance with mutual exclusion: https://dotnetfiddle.net/CkK674
Flettu sometimes does not provide reentrance, sometimes throws a semaphore count exception, or otherwise does not provide mutual exclusion: https://dotnetfiddle.net/o0c7j7
CellWars.Threading.AsyncLock does not provide mutual exclusion: https://dotnetfiddle.net/Tz38lN
I've encountered a weird behavior regarding async extension methods in separate assemblies.
We have the following:
One assembly handling sending of EventGridEvent. Target is .NET Standard 2.0. This assembly references Microsoft.Azure.EventGrid.
One assembly using assembly no. 1. Target is .NET Framework 4.7.
For some reason, making synchronous methods from assembly no. 2 to assembly no. 1 results in weird behaviour. Consider the two functions we have in assembly no. 1:
public async Task PublishAsync(...)
{
await _eventGridClient.PublishEventsAsync(_eventGridTopicHostName, ...);
}
public void Publish(...)
{
_eventGridClient.PublishEventsAsync(_eventGridTopicHostName, ...).Wait();
}
If we call the first method from assembly no. 2 with PublishAsync().Wait(), it will never return. Publish() will, however. But, if Publish() calls PublishAsync().Wait(), that method will also hang.
Worth mentioning is that EventGridClient contains LongRunningOperationRetryTimeout with default set to 30, which is ignored. It never returns.
Anyone have any idea what causes this behavior? A workaround is to copy code, but we would like to avoid that.
Thanks in advance.
You should never block on async code by calling Wait() or .Result on the returned Task. #Stephen Cleary explains why on his blog.
When _eventGridClient.PublishEventsAsync is called, the SynchronizationContext is captured. When the task completes, it waits for the context to become available but it never will since you are blocking it with your call to .Wait(). This leads to a deadlock.
You may get of out trouble by avoiding capturing the context by calling ConfigureAwait(false):
public async Task PublishAsync(...)
{
await _eventGridClient.PublishEventsAsync(_eventGridTopicHostName, ...)
.ConfigureAwait(false);
}
But the best solution is still not to block at all. Async code should be "async all the way" as explained in the linked blog post.
The problem was that the calling method was running on a UI thread. It was solved by wrapping the call like so: Task.Run(() => ...).Wait()
Summary: In a library method, when should I use the async and await keywords instead of returning a Task directly?
I believe my question is related to this one. However, that question is about .NET 4.0 and the TPL, while I'm using .NET 4.6 with the async and await keywords. So, I think my question might get different answers because these keywords didn't exist when the linked question was answered.
Explanation: I'm writing a simple wrapper for an external WCF service and the wrapper makes multiple SendAsync calls. Now I think that each wrapper method should just return a Task<> directly without being awaited. My understanding is that async/await should be used on the application layer, and not within a library.
So, for example, here is the approach that I think I should take for each wrapper method:
private Task<SignResponse> GetSignDataAsync(SigningRequestType request)
{
return _service.SendAsync(request);
}
But on the Internet, I found several posts that use this approach instead:
private async Task<SignResponse> GetSignDataAsync(SigningRequestType request)
{
return await _service.SendAsync(request).ConfigureAwait(false);
}
And here is another example that I found on technet:
async Task PutTaskDelay()
{
await Task.Delay(5000);
}
private async void btnTaskDelay_Click(object sender, EventArgs e)
{
await PutTaskDelay();
MessageBox.Show("I am back");
}
So, when should I use the second approach (the one that includes the async and await keywords)? Why not just return a whole Task without making PutTaskDelay async? I think that I should return Task directly whenever it is possible, and use async/await to get a final result in the application layer only. Am I right? If not, what is the difference between the two approaches that I show here?
My concern: When the async and await keywords are used, it seems that it just provides additional work to the compiler without any benefit.
Should I use async await in library?
It all depends. If you're going to take advantage of the asynchronous programming paradigm, then the answer is "yes," the async and await keywords are needed most of the time. More than likely, you will find yourself needing to use async/await. That is because in most situations it would be difficult to use only Task and Task<T> as you will more than likely need to reason about the results of the async operations that you invoke.
Additionally, based on your question it seems as though you may have some confusion about the keywords themselves and how they relate to the Task and Task<T> types. Allow me to clarify this for you.
The async keyword allows a method to use the await keyword. The best practice is to have all async methods return either Task or Task<T> unless you are unable to (for example, a button click event handler as you demonstrated above).
Methods that return Task or Task<T> represent asynchronous operations. When you are in a library it is suggested to always use .ConfigureAwait(false) for reasons detailed here. Additionally, I always point people to this detailed article on the subject.
To differentiate the two approaches in your question:
The method below returns a Task<SignResponse>. This is an async operation that represents the work to sign in. The method can be awaited by the caller to get SignResponse.
private Task<SignResponse> GetSignDataAsync(SigningRequestType request)
{
return _service.SignAsync(request);
}
Likewise, this version does the same thing...except that the async/await keywords are not needed. The reason they are not needed is that the method itself does not need to use SignResponse and therefore it could simply return Task<SignResponse> as shown above. And as you indicated in your question, there is indeed a penalty when you use the async/await keywords when they are not needed. Doing so adds an extra state machine step as the result is yielded, since its awaited.
private async Task<SignResponse> GetSignDataAsync(SigningRequestType request)
{
return await _service.SignAsync(request).ConfigureAwait(false);
}
Finally, if you needed to reason about the response, you could use the aforementioned keywords to do so like this:
private async Task<SignResponse> GetSignDataAsync(SigningRequestType request)
{
var result = await _service.SignAsync(request).ConfigureAwait(false);
if (result.SomeProperty == SomethingWeCareToCheck)
{
_log.Log("Wow, this was un-expected...");
}
return result;
}
Don't take my word for it, because I never understood async/await that well, but what bothered me most about the idea was that all methods using async had to be marked as async as well, which annoyed me to no end.
I guess in a library giving people the option to choose how to use the methods is a good thing, so you should use async, however I always found it more clear to explicitly use the Tasks directly.
Assume I have a method that has void return type and that I need to await on an operation in this method.
public void someOperation()
{
//dostuff
var res = await someOtherOperation();
//do some other stuff that needs res.
}
When I tried to compile this code I got the error saying someOperation has to be declare async. I don't understand why. I understand why it would if the method had a return value, but not here when it's void. or even in the case when the awaiting operation has no effect on the return value of method.
This has already been asked as a part of this question but I didn't find the answer I was looking for. This guy merely mentions:
The async keyword enables the await keyword. So any method using await
must be marked async.
First of all, I'm not sure what it means that async keyword enables await keyword.
And secondly, restating my question, I'm not sure why it is required?
Asynchronous methods must be marked async. The async and await keywords are paired together, primarily for backwards-compatibility reasons; await was a valid identifier (not a keyword), so when it was added to the language, they also added the async keyword.
Alternatively, they could have gone with a multi-word keyword for await, such as await for. However, the language design team decided to go with the pairing, since it clearly and explicitly marks all async methods - it's easier for both compilers and humans to parse.
I have a blog post on the subject, with links to Eric Lippert's definitive blog post as well as discussions in blog comments, Channel9 forums, MSDN forums, and of course right here on Stack Overflow.
Note that the natural return type of an async method without a result value is Task, not void. void is an unnatural return type for async methods. So your default reaction when seeing the "await operator must be within an async method" error should be to mark it async and change the return type from void to Task:
public async Task someOperationAsync()
{
//dostuff
var res = await someOtherOperationAsync();
//do some other stuff that needs res.
}
This follows one of the best practices in my MSDN article on the subject: avoid async void. async void was allowed by the language designers for event handlers (or code that is logically an event handler, like ICommand.Execute); any other usage is going to cause problems.
I don't understand why.
Because you need to tell the compiler that you're trying to write an async method. That's exactly what the document you're quoting means.
The compiler could infer that from whether or not your method includes any await expressions - but that would mean you could comment out one line of a method and the whole method's behaviour would radically change. (Think about exception handling, for example...)
It also improves readability - it means anyone reading your code knows this is an async method right from the start.
So basically, the answers are:
You need to because the language specification requires you to. The compiler is implementing the language specification.
The language specification requires you to because it reduces the element of surprise.
Because they must work in pair in C#. It is the rule.
The “async” keyword enables the “await” keyword in that method and changes how method results are handled. That’s all the async keyword does! It does not run this method on a thread pool thread, or do any other kind of magic. The async keyword only enables the await keyword (and manages the method results).
How do you avoid writing the same code twice for an async and a non async method.
I am currently using ASP.NET so I am currently on the request thread, and I quickly learned that he below code (that should show my intent), is definetely the wrong way of doing this.
The application deadlocks, as the await keyword tries to get back on the same thread that the .Result is blocking.
The whole reason I am doing this, is to avoid writing the same "FindAll" code twice.
public IEnumerable<Resource> FindAll()
{
return FindAllAsync().Result;
}
public async Task<IEnumerable<Resource>> FindAllAsync()
{
return await Context.Resources.ToListAsync();
}
So how do you solve this?
How do you avoid writing the same code twice for an async and a non async method.
You can't, in the general case.
The operation in question is either naturally asynchronous or naturally synchronous. In this example (a database request), it is naturally asynchronous. So, make the API asynchronous. That is all.
Stephen Toub has a famous pair of blog posts Should I expose synchronous wrappers for asynchronous methods? and Should I expose asynchronous wrappers for synchronous methods? The short answer to both questions is "no."
You can do various hacks to expose both types of APIs (and Stephen covers each approach in his posts), but the benefits are minuscule compared to the drawbacks.
Synchronous and Asynchronous methods should act differently. Usually that means that synchronous calls should call an API that blocks as a part of the request and async should call the API that is "async all the way"
If you don't want to create a completely synchronous api, in your case, you can use ConfigureAwait(false).
When you mark a Task with ConfigureAwait(false), what you're actually saying is "There's no need to run the continuation (the code after the await) inside the same SynchronizationContext, you may complete inside your current context (Which is usually a ThreadPool thread)"
As for your second method, you can remove the async keyword and save a redundant generation of a state machine:
public IEnumerable<Resource> FindAll()
{
return FindAllAsync().Result;
}
public Task<IEnumerable<Resource>> FindAllAsync()
{
return Context.Resources.ToListAsync();
}
Some reading references:
Stephan Cleary - Dont block on async code
Best practice to call ConfigureAwait(false)
Task.ConfigureAwait(false) MSDN