C
C#2y ago
Eistee

❔ ConfigureAwait(false) (IntelliCode Suggestion)

Can someone help me to understand why IntelliCode is suggesting ConfigureAwait(false) at line 16 await Dns.GetHostEntryAsync(ipAddress);? Would this really result in an advantage?
private async Task<List<DeviceInfo>> GetDevices(XDocument xDocument)
{
List<DeviceInfo> deviceList = new List<DeviceInfo>();

var itemElements = xDocument.Descendants("item");
foreach (var itemElement in itemElements)
{
string? deviceName = itemElement.Element("device")?.Value;
string? host = itemElement.Element("host")?.Value;
string? objId = itemElement.Element("objid")?.Value;

if (IPAddress.TryParse(host, out IPAddress? ipAddress) && ipAddress.AddressFamily == System.Net.Sockets.AddressFamily.InterNetwork)
{
try
{
var hostEntry = await Dns.GetHostEntryAsync(ipAddress);
host = hostEntry.HostName;
}
catch
{
_logger.LogError($"There is an error occured while resolving {ipAddress}: {host}");
}
}

// remove all possible domains from FQDNs to get hostnames even if they include dots
if (_optionsAccessor.PossibleOccuringDomains is not null && !string.IsNullOrEmpty(host))
{
deviceName = host;
_optionsAccessor.PossibleOccuringDomains.ForEach(item =>
{
deviceName = deviceName.Replace(item, string.Empty);
});
}

deviceList.Add(new DeviceInfo { HostName = deviceName, FQDN = host, ObjID = objId });
}
return deviceList;
}
private async Task<List<DeviceInfo>> GetDevices(XDocument xDocument)
{
List<DeviceInfo> deviceList = new List<DeviceInfo>();

var itemElements = xDocument.Descendants("item");
foreach (var itemElement in itemElements)
{
string? deviceName = itemElement.Element("device")?.Value;
string? host = itemElement.Element("host")?.Value;
string? objId = itemElement.Element("objid")?.Value;

if (IPAddress.TryParse(host, out IPAddress? ipAddress) && ipAddress.AddressFamily == System.Net.Sockets.AddressFamily.InterNetwork)
{
try
{
var hostEntry = await Dns.GetHostEntryAsync(ipAddress);
host = hostEntry.HostName;
}
catch
{
_logger.LogError($"There is an error occured while resolving {ipAddress}: {host}");
}
}

// remove all possible domains from FQDNs to get hostnames even if they include dots
if (_optionsAccessor.PossibleOccuringDomains is not null && !string.IsNullOrEmpty(host))
{
deviceName = host;
_optionsAccessor.PossibleOccuringDomains.ForEach(item =>
{
deviceName = deviceName.Replace(item, string.Empty);
});
}

deviceList.Add(new DeviceInfo { HostName = deviceName, FQDN = host, ObjID = objId });
}
return deviceList;
}
18 Replies
kocha
kocha2y ago
It would increase performance, but unless you know exactly what it is doing, i would nod recommend it.
Connor
Connor2y ago
It wouldn’t increase performance. It would change the synchronization context that the callback uses.
kocha
kocha2y ago
Yes, but to change the synchronisation context takes a bit of time, so not doing it increases performance If you actually have one, which is only really the case in gui applications
Connor
Connor2y ago
I guess your right
mtreit
mtreit2y ago
The suggestion has little to do with performance. It's a best practice to always use ConfigureAwait(false) if you are writing code in a library that does not need to capture the syncrhonization context. It avoids the possibility of deadlocks if some consumer of your code decides to call .Result or .Wait (which is usually a poor practice, but it happens in the real world all the time.)
kocha
kocha2y ago
I would disagree, microsoft themself say that the reason is performance and deadlock related: https://devblogs.microsoft.com/dotnet/configureawait-faq/
Stephen Toub - MSFT
.NET Blog
ConfigureAwait FAQ - .NET Blog
.NET added async/await to the languages and libraries over seven years ago. In that time, it’s caught on like wildfire, not only across the .NET ecosystem, but also being replicated in a myriad of other languages and frameworks. It’s also seen a ton of improvements in .NET,
mtreit
mtreit2y ago
I'm familiar with that post and I agree with everything in it. Just that performance is not the primary reason to use ConfigureAwait(false)...
kocha
kocha2y ago
Ok, i see
mtreit
mtreit2y ago
I wonder if I have a benchmark for this...
kocha
kocha2y ago
Depends 100% on what the synchronisation context actually does.
mtreit
mtreit2y ago
Ah yes, I do
kocha
kocha2y ago
This is a console app, it doesnt even have a synchronisation context, or am im I missing something
mtreit
mtreit2y ago
It has the default synchronization context (which is the thread pool) It's entirely possible that it's a noop for the default task scheduler I never checked Although the benchmark numbers do seem to show that ConfigureAwait(true) has some small overhead
mtreit
mtreit2y ago
mtreit
mtreit2y ago
Congratulations @kocha you have lead me down a complete rabbit hole: https://discord.com/channels/143867839282020352/143867839282020352/1133887368131264532
MODiX
MODiX2y ago
mtreit
public long ReadAsyncAwaitCustomContextConfigureAwaitFalse()
{
long result = 0;

using var sr = new StreamReader(_testFile);

string line;

while ((line = AsyncContext.Run(async () => { var res = await sr.ReadLineAsync().ConfigureAwait(false); Console.WriteLine($"{res} -> {SynchronizationContext.Current?.GetType().Name ?? "<null>"}"); return res; })) != null)
{
result += int.Parse(line);
}

return result;
}
public long ReadAsyncAwaitCustomContextConfigureAwaitFalse()
{
long result = 0;

using var sr = new StreamReader(_testFile);

string line;

while ((line = AsyncContext.Run(async () => { var res = await sr.ReadLineAsync().ConfigureAwait(false); Console.WriteLine($"{res} -> {SynchronizationContext.Current?.GetType().Name ?? "<null>"}"); return res; })) != null)
{
result += int.Parse(line);
}

return result;
}
I have a two line file. Literally these bytes:
Offset Bytes Ascii
00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F
------ ----------------------------------------------- -----
0000000000000000 30 0D 0A 31 0D 0A 0��1��
Offset Bytes Ascii
00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F
------ ----------------------------------------------- -----
0000000000000000 30 0D 0A 31 0D 0A 0��1��
If I feed this file to the above code, what does it print out?
Quoted by
<@406536255426396160> from #chat (click here)
React with ❌ to remove this embed.
Accord
Accord2y ago
Was this issue resolved? If so, run /close - otherwise I will mark this as stale and this post will be archived until there is new activity.

Did you find this page helpful?