Skip to content

Commit

Permalink
Changes for v0.1.20 (#59)
Browse files Browse the repository at this point in the history
  • Loading branch information
tonyredondo committed Sep 19, 2024
1 parent 27c7da1 commit 7040d4a
Show file tree
Hide file tree
Showing 12 changed files with 1,091 additions and 334 deletions.
4 changes: 3 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
bin/
obj/
.idea/
.DS_Store
.DS_Store
*.nupkg
*.DotSettings.user
522 changes: 288 additions & 234 deletions README.md

Large diffs are not rendered by default.

4 changes: 2 additions & 2 deletions src/Directory.Build.props
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
<Project>
<PropertyGroup>
<Version>0.1.19</Version>
<Version>0.1.20</Version>
<Authors>Tony Redondo, Grégory Léocadie</Authors>
<TargetFrameworks>net6.0;net7.0;net8.0</TargetFrameworks>
<ImplicitUsings>enable</ImplicitUsings>
Expand All @@ -10,6 +10,6 @@
</PropertyGroup>

<ItemGroup>
<PackageReference Include="DotNet.ReproducibleBuilds" Version="1.1.1" PrivateAssets="All"/>
<PackageReference Include="DotNet.ReproducibleBuilds" Version="1.2.25" PrivateAssets="All"/>
</ItemGroup>
</Project>
147 changes: 147 additions & 0 deletions src/TimeItSharp.Common/AsyncUtil.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,147 @@
namespace TimeItSharp.Common;

/*
* This code based on:
* https://www.ryadel.com/en/asyncutil-c-helper-class-async-method-sync-result-wait/
*
* WARNING: this class should be only used as a last resort for awaiting a Task in
* a sync context.
*/

/// <summary>
/// Helper class to run async methods within a sync process.
/// </summary>
internal static class AsyncUtil
{
private static readonly TaskFactory _taskFactory = new(CancellationToken.None, TaskCreationOptions.None, TaskContinuationOptions.None, TaskScheduler.Default);

/// <summary>
/// Gets the TaskFactory instance for this class.
/// </summary>
public static TaskFactory Factory => _taskFactory;

/// <summary>
/// Executes an async Task method which has a void return value synchronously
/// USAGE: AsyncUtil.RunSync(() => AsyncMethod());
/// </summary>
/// <param name="task">Task method to execute</param>
public static void RunSync(Func<Task> task)
=> _taskFactory
.StartNew(task)
.Unwrap()
.GetAwaiter()
.GetResult();

/// <summary>
/// Executes an async Task method which has a void return value synchronously
/// USAGE: AsyncUtil.RunSync(() => AsyncMethod(), cancellationToken);
/// </summary>
/// <param name="task">Task method to execute</param>
/// <param name="cancellationToken">Cancellation token</param>
public static void RunSync(Func<Task> task, CancellationToken cancellationToken)
=> _taskFactory
.StartNew(task, cancellationToken)
.Unwrap()
.GetAwaiter()
.GetResult();

/// <summary>
/// Executes an async Task method which has a void return value synchronously
/// USAGE: AsyncUtil.RunSync(() => AsyncMethod(), millisecondsTimeout);
/// </summary>
/// <param name="task">Task method to execute</param>
/// <param name="millisecondsTimeout">Timeout in milliseconds</param>
public static void RunSync(Func<Task> task, int millisecondsTimeout)
{
_taskFactory
.StartNew(TaskWithTimeoutAsync)
.Unwrap()
.GetAwaiter()
.GetResult();

Task TaskWithTimeoutAsync()
{
var runTask = task();
return runTask.IsCompleted
? runTask
: runTask.WaitAsync(TimeSpan.FromMilliseconds(millisecondsTimeout));
}
}

/// <summary>
/// Executes an async Task method which has a void return value synchronously
/// USAGE: AsyncUtil.RunSync(ex => AsyncMethod(ex), new Exception(), millisecondsTimeout);
/// </summary>
/// <param name="task">Task method to execute</param>
/// <param name="state">State that is passed to the running function</param>
/// <param name="millisecondsTimeout">Timeout in milliseconds</param>
public static void RunSync<T>(Func<T, Task> task, T state, int millisecondsTimeout)
{
_taskFactory
.StartNew(TaskWithTimeoutAsync)
.Unwrap()
.GetAwaiter()
.GetResult();

Task TaskWithTimeoutAsync()
{
var runTask = task(state);
return runTask.IsCompleted
? runTask
: runTask.WaitAsync(TimeSpan.FromMilliseconds(millisecondsTimeout));
}
}

/// <summary>
/// Executes an async Task[T] method which has a T return type synchronously
/// USAGE: T result = AsyncUtil.RunSync(() => AsyncMethod[T]());
/// </summary>
/// <typeparam name="TResult">Return Type</typeparam>
/// <param name="task">Task[T] method to execute</param>
/// <returns>TResult result</returns>
public static TResult RunSync<TResult>(Func<Task<TResult>> task)
=> _taskFactory
.StartNew(task)
.Unwrap()
.GetAwaiter()
.GetResult();

/// <summary>
/// Executes an async Task[T] method which has a T return type synchronously
/// USAGE: T result = AsyncUtil.RunSync(() => AsyncMethod[T](), cancellationToken);
/// </summary>
/// <typeparam name="TResult">Return Type</typeparam>
/// <param name="task">Task[T] method to execute</param>
/// <param name="cancellationToken">Cancellation token</param>
/// <returns>TResult result</returns>
public static TResult RunSync<TResult>(Func<Task<TResult>> task, CancellationToken cancellationToken)
=> _taskFactory
.StartNew(task, cancellationToken)
.Unwrap()
.GetAwaiter()
.GetResult();

/// <summary>
/// Executes an async Task[T] method which has a T return value synchronously
/// USAGE: AsyncUtil.RunSync(() => AsyncMethod[T](), millisecondsTimeout);
/// </summary>
/// <typeparam name="TResult">Return Type</typeparam>
/// <param name="task">Task[T] method to execute</param>
/// <param name="millisecondsTimeout">Timeout in milliseconds</param>
public static TResult RunSync<TResult>(Func<Task<TResult>> task, int millisecondsTimeout)
{
return _taskFactory
.StartNew(TaskWithTimeoutAsync)
.Unwrap()
.GetAwaiter()
.GetResult();

Task<TResult> TaskWithTimeoutAsync()
{
var runTask = task();
return runTask.IsCompleted
? runTask
: runTask.WaitAsync(TimeSpan.FromMilliseconds(millisecondsTimeout));
}
}
}
Loading

0 comments on commit 7040d4a

Please sign in to comment.