Skip to content

Instantly share code, notes, and snippets.

View idg10's full-sized avatar

Ian Griffiths idg10

  • endjin
  • Hove, UK
View GitHub Profile
@idg10
idg10 / ParseFile.cs
Created September 7, 2018 06:39
Mishandling of resources
// Excerpt from https://blogs.msdn.microsoft.com/seteplia/2018/09/05/combining-iterator-blocks-and-async-methods-in-c/
public static IEnumerable<Task<int>> ParseFile(string path)
{
if (string.IsNullOrEmpty(path)) { throw new ArgumentNullException(nameof(path)); }
// OpenWithRetryPolicyAsync uses RetryPolicy to try to open the file more than once.
// The method throws FileNotFoundException if the file does not exists.
using (var file = OpenWithRetryPolicyAsync(path).Result)
{
@idg10
idg10 / ParseFile-declaration.cs
Created September 7, 2018 06:59
ParseFile declaration
public static IEnumerable<Task<int>> ParseFile(string path)
@idg10
idg10 / ParseFileUseFirst.cs
Created September 7, 2018 07:16
Taking the first task in an IEnumerable<Task<int>>
Task<int> firstTask = ParseFile(path).First();
@idg10
idg10 / ParseFileUseSecond.cs
Last active September 11, 2018 06:13
Skipping the first task in an IEnumerable<Task<int>> and taking the second
// Never do this!
Task<int> firstTask = ParseFile(path).Skip(1).First();
@idg10
idg10 / FuncDeferralResourceMishandling.cs
Last active September 11, 2018 07:26
Incorrect resource handling with Func-based deferred execution
// This doesn't work.
public static Func<string> GetContentGetter(string configPath)
{
using (var reader = new StreamReader(configPath))
{
return () => reader.ReadToEnd();
}
}
@idg10
idg10 / TaskDeferralResourceMishandling.cs
Created September 19, 2018 05:55
Incorrect resource handling with Task-based deferred execution
// This doesn't work.
public static Task<string> GetContentAsync(string configPath)
{
using (var reader = new StreamReader(configPath))
{
return reader.ReadToEndAsync();
}
}
@idg10
idg10 / TaskDeferralFixed.cs
Created September 19, 2018 05:58
Fixed resource handling with Task-based deferred execution
public static async Task<string> GetContentAsync(string configPath)
{
using (var reader = new StreamReader(configPath))
{
return await reader.ReadToEndAsync();
}
}
@idg10
idg10 / EnumerableTaskDeferralResourceMishandling.cs
Last active September 19, 2018 06:14
Incorrect resource handling with combined enumerable and Task-based deferred execution
// This won't work
public static IEnumerable<Task<int>> ParseFile(string path)
{
using (var reader = new StreamReader(path))
{
while (!reader.EndOfStream)
{
yield return ReadAndParseAsync(reader);
}
}
@idg10
idg10 / EnumerableTaskDeferralResourceHandlingFixed.cs
Last active September 19, 2018 09:55
Resource handling with combined enumerable and Task-based deferred execution, ensuring correct sequencing
public static IEnumerable<Task<int>> ParseFile(string path)
{
using (var reader = new StreamReader(path))
{
while (!reader.EndOfStream)
{
Task<int> readLineTask = null;
try
{
readLineTask = ReadAndParseAsync(reader);
@idg10
idg10 / FunctionSignatureWithOutParameter.cs
Created February 22, 2019 12:57
A C# function signature with an out parameter
public static bool Read(int[] buffer, out int bytesRead)