试图找出构建此问题解决方案的最佳方法
处理身份验证中间件时的HTTP请求管道。在JwtBearerOptions中运行OnTokenValidated与我的请求代码并行执行。我可以同步运行,但我不愿意,
我的部分要求要求此声明,我如何确保已设置此声明?
我的代码:
public class TaskManager : ITaskManager
{
Dictionary<string, Task> _taskAwaiterMap = new Dictionary<string, Task>();
public Task GetTaskForKey(string key)
{
this._taskAwaiterMap.TryGetValue(key, out var awaiter);
return awaiter;
}
public void QueueTask(string key, Task task)
{
this._taskAwaiterMap[key] = task;
}
}
修改
public async Task GetManditoryTaskForKey(string key, int timeout)
{
var cancellationTokenSource = new CancellationTokenSource(timeout);
await GetManditoryResolverWaitTask(key, cancellationTokenSource.Token);
}
protected async Task<Task> GetManditoryResolverWaitTask(string key, CancellationToken cancellationToken)
{
while (false == this._taskAwaiterMap.TryGetValue(key, out var task))
{
if(cancellationToken.IsCancellationRequested)
{
return Task.FromCanceled(cancellationToken);
}
await Task.Yield();
}
return this.GetTaskForKey(key);
}
我找到了一种等待设置密钥的方法,但这是同步异步任务的有效方法吗?
修改
在我的Http Pipe Line中,我会像这样排队任务:
OnTokenValidated = async tvc => { await AuthenticationRule.ValidateToken(tvc); }
//... Source ValidateToken
//Some Potentially long Task
var awaitManager = serviceProvider.GetRequiredService<ITaskManager>();
var userClaimsTask = SetUserClaims(claimsIdentity, context, userSubjectId);
awaitManager.QueueTask(USER_CLAIM_AWAITER_KEY, userClaimsTask);
如何有效地同步我的异步任务?
答案 0 :(得分:2)
我试图回答你之前提出的问题。 :)
无论如何,我不确定这是解决问题的最佳方法,因为我不熟悉Async HTTP管道。但以下可以解决您正在采取的方法:
public class TaskManager : ITaskManager
{
private readonly ConcurrentDictionary<string, TaskCompletionSource<Task>> _taskAwaiterMap = new ConcurrentDictionary<string, TaskCompletionSource<Task>>();
public async Task GetTaskForKey(string key)
{
await await this._taskAwaiterMap.GetOrAdd(key, _ => new TaskCompletionSource<Task>()).Task;
}
public void QueueTask(string key, Task task)
{
this._taskAwaiterMap.GetOrAdd(key, _ => new TaskCompletionSource<Task>()).SetResult(task);
}
}
我认为TaskManager只会在会话中存在。否则,您将不得不考虑如何清理_taskAwaiterMap
。