繁体   English   中英

跨线程同步异步任务

[英]Syncronizing Async Tasks Across Threads

试图找出解决此问题的最佳方法

处理身份验证中间件时的HTTP请求管道。 在JwtBearerOptions中运行OnTokenValidated与我的请求代码并行执行。 我可以同步运行它,但我不想这样做,

我的某些请求需要此声明,如何确保已设置此声明?

  1. 我正在并行运行两个线程,
  2. 一个异步函数依赖于另一个线程来设置变量
  3. 我创建了一个等待经理来完成任务。
  4. 但是,等待管理器有可能没有设置任务密钥,因为我没有执行。

我的代码:

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);

如何有效地同步我的异步任务?

我试图回答你以前的问题。 :)

无论如何,我不确定这是否是解决您问题的最佳解决方案,因为我对异步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

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM