asp.net core 中的排队任务

例如功能 有 20 个用户,他们几乎一次点击了发送按钮,所以方法堆叠在队列中,第一个用户消息被发送并收到响应,在第二个第三个之后,依此类推。用户不会与其他人聊天,但使用响应非常快的设备

所以我试图将发送消息的任务排队。

我找到了使用任务队列的代码示例,如示例 1和示例 2 所示。


示例 1


public class SerialQueue

{

    readonly object _locker = new object();

    WeakReference<Task> _lastTask;


    public Task Enqueue(Action action)

    {

        return Enqueue<object>(() => {

            action();

            return null;

        });

    }


    public Task<T> Enqueue<T>(Func<T> function)

    {

        lock (_locker)

        {

            Task lastTask = null;

            Task<T> resultTask = null;


            if (_lastTask != null && _lastTask.TryGetTarget(out lastTask))

            {

                resultTask = lastTask.ContinueWith(_ => function());

            }

            else

            {

                resultTask = Task.Run(function);

            }


            _lastTask = new WeakReference<Task>(resultTask);

            return resultTask;

        }

    }

}


示例 2


 public class TaskQueue

{

    private readonly SemaphoreSlim _semaphoreSlim;


    public TaskQueue()

    {

        _semaphoreSlim = new SemaphoreSlim(1);

    }


    public async Task<T> Enqueue<T>(Func<Task<T>> taskGenerator)

    {

        await _semaphoreSlim.WaitAsync();


        try

        {

            return await taskGenerator();

        }

        finally

        {

            _semaphoreSlim.Release();

        }

    }


    public async Task Enqueue(Func<Task> taskGenerator)

    {

        await _semaphoreSlim.WaitAsync();

        try

        {

            await taskGenerator();

        }

        finally

        {

            _semaphoreSlim.Release();

        }

    }

}


问题是,当我每次按下按钮时传递我想要排队的任务(示例 3)时,任务仍然同时执行并相互中断。


我如何解决问题并将任务堆叠到每次单击时排队?


烙印99
浏览 461回答 1
1回答

DIEA

你的问题是,你创建一个新的TaskQueue和SerialQueue每次。这样每次用户点击/调用PostMessage都会创建一个新的队列,任务是队列中的第一个任务,直接执行。您应该使用静态/单例队列,以便每次单击/调用都适用于同一个队列对象。但是,当您跨多个服务器扩展 Web 应用程序时,这会带来问题。为此,您应该将诸如(例如)Azure 队列存储之类的东西与 Azure Functions 结合使用。启动文件public void ConfigureServices(IServiceCollection services){&nbsp; &nbsp; services.AddSingleton<TaskQueue>();&nbsp; &nbsp; services.AddSingleton<SerialQueue>();&nbsp; &nbsp; // the rest}一些控制器.cs[HttpPost(Name = "add-message")]public async Task<IActionResult> PostMessage(&nbsp; &nbsp; [FromBody] MessengerViewModel messengerViewModel,&nbsp; &nbsp; [FromServices] TaskQueue taskQueue,&nbsp; &nbsp; [FromServices] SerialQueue serialQueue){&nbsp; &nbsp; await taskQueue.Enqueue(&nbsp; &nbsp; &nbsp; &nbsp; () => SendMessage(&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; messengerViewModel.PhoneNr,&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; messengerViewModel.MessageBody,&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; messengerViewModel.ContactId,&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; messengerViewModel.State));&nbsp; &nbsp; //I'm not running tasks at same time, using one or other at time&nbsp; &nbsp; await serialQueue.Enqueue(&nbsp; &nbsp; &nbsp; &nbsp; () => SendMessage(&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; messengerViewModel.PhoneNr,&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; messengerViewModel.MessageBody,&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; messengerViewModel.ContactId,&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; messengerViewModel.State));&nbsp; &nbsp; return Ok();}
打开App,查看更多内容
随时随地看视频慕课网APP