Skip to content

Commit

Permalink
支持在 KeepLastReentrancyTask 配置是否需要回到原来的线程
Browse files Browse the repository at this point in the history
  • Loading branch information
lindexi committed Mar 2, 2022
1 parent fec4b8b commit 958f165
Showing 1 changed file with 18 additions and 4 deletions.
22 changes: 18 additions & 4 deletions AsyncWorkerCollection/Reentrancy/KeepLastReentrancyTask.cs
Original file line number Diff line number Diff line change
Expand Up @@ -48,12 +48,24 @@ sealed class KeepLastReentrancyTask<TParameter, TReturn> : ReentrancyTask<TParam
/// </summary>
private readonly Queue<TaskWrapper> _skipQueue = new Queue<TaskWrapper>();

private readonly bool _configureAwait;

/// <summary>
/// 创建以KeepLast策略执行的可重入任务。
/// </summary>
/// <param name="task">可重入任务本身。</param>
public KeepLastReentrancyTask(Func<TParameter, Task<TReturn>> task) : base(task) { }

/// <summary>
/// 创建以KeepLast策略执行的可重入任务。
/// </summary>
/// <param name="task">可重入任务本身。</param>
/// <param name="configureAwait"></param>
public KeepLastReentrancyTask(Func<TParameter, Task<TReturn>> task, bool configureAwait) : this(task)
{
_configureAwait = configureAwait;
}

/// <summary>
/// 以KeepLast策略执行重入任务,并获取此次重入任务的返回值。
/// 此重入策略会确保执行当前队列中的最后一个任务,并对所有当前队列任务赋值该任务结果。
Expand All @@ -62,7 +74,7 @@ public KeepLastReentrancyTask(Func<TParameter, Task<TReturn>> task) : base(task)
/// <returns>重入任务本次执行的返回值。</returns>
public override Task<TReturn> InvokeAsync(TParameter arg)
{
var wrapper = new TaskWrapper(() => RunCore(arg));
var wrapper = new TaskWrapper(() => RunCore(arg), _configureAwait);
_queue.Enqueue(wrapper);
Run();
return wrapper.AsTask();
Expand Down Expand Up @@ -106,7 +118,7 @@ private async void Run()
if (runTask != null)
{
// 内部已包含异常处理,因此外面可以无需捕获或者清理。
await runTask.RunAsync().ConfigureAwait(false);
await runTask.RunAsync().ConfigureAwait(_configureAwait);
//完成后对等待队列中的项赋值
if (runTask.Exception != null)
{
Expand Down Expand Up @@ -156,14 +168,16 @@ private class TaskWrapper
/// <summary>
/// 创建一个任务包装。
/// </summary>
internal TaskWrapper(Func<Task<TReturn>> workingTask)
internal TaskWrapper(Func<Task<TReturn>> workingTask, bool configureAwait)
{
_taskSource = new TaskCompletionSource<TReturn>();
_task = workingTask;
_configureAwait = configureAwait;
}

private readonly TaskCompletionSource<TReturn> _taskSource;
private readonly Func<Task<TReturn>> _task;
private readonly bool _configureAwait;

public TReturn Result { get; set; }
public Exception Exception { get; set; }
Expand All @@ -180,7 +194,7 @@ internal async Task RunAsync()
{
throw new InvalidOperationException("在指定 KeepLastReentrancyTask 的任务时,方法内不允许返回 null。请至少返回 Task.FromResult<object>(null)。");
}
var result = await task.ConfigureAwait(false);
var result = await task.ConfigureAwait(_configureAwait);
_taskSource.SetResult(result);
Result = result;
}
Expand Down

0 comments on commit 958f165

Please sign in to comment.