C
C#17mo 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
anita
anita17mo ago
It would increase performance, but unless you know exactly what it is doing, i would nod recommend it.
Connor
Connor17mo ago
It wouldn’t increase performance. It would change the synchronization context that the callback uses.
anita
anita17mo 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
Connor17mo ago
I guess your right
mtreit
mtreit17mo 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.)
anita
anita17mo 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
mtreit17mo 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)...
anita
anita17mo ago
Ok, i see
mtreit
mtreit17mo ago
I wonder if I have a benchmark for this...
anita
anita17mo ago
Depends 100% on what the synchronisation context actually does.
mtreit
mtreit17mo ago
Ah yes, I do
anita
anita17mo ago
This is a console app, it doesnt even have a synchronisation context, or am im I missing something
mtreit
mtreit17mo 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
mtreit17mo ago
mtreit
mtreit17mo ago
Congratulations @kocha you have lead me down a complete rabbit hole: https://discord.com/channels/143867839282020352/143867839282020352/1133887368131264532
MODiX
MODiX17mo 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
Accord17mo 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.
Want results from more Discord servers?
Add your server