Skip to content

Instantly share code, notes, and snippets.

@guojianwei001
Last active May 30, 2022 13:01
Show Gist options
  • Save guojianwei001/95a3374705293399d562a4caca18dd20 to your computer and use it in GitHub Desktop.
Save guojianwei001/95a3374705293399d562a4caca18dd20 to your computer and use it in GitHub Desktop.
Convert old BeginRead/EndRead asyn method to async/await method; implete a simple FromAsync similar to Task.Factory.FromAsync
#nullable enable
using System;
using System.IO;
using System.Threading.Tasks;
namespace AsyncAwaitPlay
{
class Program
{
/*
*References:
* https://devblogs.microsoft.com/dotnet/migrating-delegate-begininvoke-calls-for-net-core/
* https://docs.microsoft.com/en-us/dotnet/standard/asynchronous-programming-patterns/interop-with-other-asynchronous-patterns-and-types
* https://gist.github.com/emoacht/aa1f919a0dc6b6906d41
* https://docs.microsoft.com/en-us/dotnet/api/system.threading.tasks.taskcompletionsource-1?view=net-6.0
*/
static async Task Main(string[] args)
{
// case 1: By Task.Factory.FromAsync, convert the old style of async beginMethod/EndMethod to async/await style
var result = await ReadFileAsync("testfile.txt");
Console.WriteLine(result); // content should be: "This is a test file."
// case 2: Implement a simple FromAsync methold similar as Task.Factory.FromAsync, do this conversion
//var result = await MyReadFileAsync("testfile.txt");
//Console.WriteLine(result); // content should be: "This is a test file."
Console.ReadKey();
}
static async Task<string> ReadFileAsync(string filePath)
{
if (!File.Exists(filePath))
return null;
using (var fs = new FileStream(filePath, FileMode.Open, FileAccess.Read))
{
var buff = new byte[fs.Length];
return await Task.Factory.FromAsync(fs.BeginRead, fs.EndRead, buff, 0, buff.Length, TaskCreationOptions.None)
.ContinueWith(_ =>
{
using (var ms = new MemoryStream(buff))
using (var sr = new StreamReader(ms))
return sr.ReadToEnd();
});
}
}
static async Task<string> MyReadFileAsync(string filePath)
{
if (!File.Exists(filePath))
return null;
using (var fs = new FileStream(filePath, FileMode.Open, FileAccess.Read))
{
var buff = new byte[fs.Length];
return await FromAsync(fs.BeginRead, fs.EndRead, buff, 0, buff.Length, TaskCreationOptions.None)
.ContinueWith(_ =>
{
using (var ms = new MemoryStream(buff))
using (var sr = new StreamReader(ms))
return sr.ReadToEnd();
});
}
}
static Task<TResult> FromAsync<TArg1, TArg2, TArg3, TResult>(
Func<TArg1, TArg2, TArg3, AsyncCallback, object?, IAsyncResult> beginMethod,
Func<IAsyncResult, TResult> endMethod,
TArg1 arg1,
TArg2 arg2,
TArg3 arg3,
object? state)
{
var tcs1 = new TaskCompletionSource<TResult>();
beginMethod(arg1, arg2, arg3, asyncResult =>
{
if (asyncResult.CompletedSynchronously == false)
{
var result = endMethod(asyncResult);
tcs1.SetResult(result);
}
}, state);
return tcs1.Task;
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment