Has anyone come across a scenario for using ConfigureAwait(true)? Since true is the default option I cannot see when would you ever use it.
Has anyone come across a scenario for using ConfigureAwait(true)? Since true is the default option I cannot see when would you ever use it.
If you are using Azure's Durable Functions, then you must use ConfigureAwait(true) when awaiting your Activity functions:
string capture = await context.CallActivityAsync<string>("GetCapture", captureId).ConfigureAwait(true);
Otherwise you will likely get the error:
"Multithreaded execution was detected. This can happen if the orchestrator function code awaits on a task that was not created by a DurableOrchestrationContext method. More details can be found in this article https://docs.microsoft.com/en-us/azure/azure-functions/durable-functions-checkpointing-and-replay#orchestrator-code-constraints.".
Further information can be found here.
A situation to use ConfigureAwait(true) is when performing await in a lock, or using any other context/thread specific resources. This requires a synchronization context, which you will have to create, unless you are using Windows Forms or WPF, which automatically create a UI synchronization context.
In the following code (assumed to be called from the UI thread and synchronization context), if ConfigureAwait(false) was used, the locks would attempt to release on a different thread, causing an exception. This is a simple example that updates a large config file if it has changed from an external source, attempting to avoid write disk IO if the config file is the same as before.
Example:
/// <summary>
/// Write a new config file
/// </summary>
/// <param name="xml">Xml of the new config file</param>
/// <returns>Task</returns>
public async Task UpdateConfig(string xml)
{
// Ensure valid xml before writing the file
XmlDocument doc = new XmlDocument();
using (XmlReader xmlReader = XmlReader.Create(new StringReader(xml), new XmlReaderSettings { CheckCharacters = false }))
{
doc.Load(xmlReader);
}
// ReaderWriterLock
configLock.AcquireReaderLock(Timeout.Infinite);
try
{
string text = await File.ReadAllTextAsync(ConfigFilePath).ConfigureAwait(true);
// if the file changed, update it
if (text != xml)
{
LockCookie cookie = configLock.UpgradeToWriterLock(Timeout.Infinite);
try
{
// compare again in case text was updated before write lock was acquired
if (text != xml)
{
await File.WriteAllTextAsync(ConfigFilePath, xml).ConfigureAwait(true);
}
}
finally
{
configLock.DowngradeFromWriterLock(ref cookie);
}
}
}
finally
{
configLock.ReleaseReaderLock();
}
}