例如功能
有20个用户,他们几乎同时点击了发送按钮,所以方法堆叠在队列中,第一个用户的消息被发送并接收到响应,然后是第二个、第三个等等。用户不会与其他人聊天,而是与设备聊天,其响应非常快。
因此,我正在尝试排队发送消息的任务。
我找到了使用任务队列的代码示例,如示例1和示例2所示。
问题在于当我将想要排队的任务传递给队列时(示例3),每次按下按钮时,任务仍然同时执行并相互中断。
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),每次按下按钮时,任务仍然同时执行并相互中断。
[HttpPost(Name = "add-message")]
public async Task<IActionResult> PostMessage([FromBody] MessengerViewModel messengerViewModel)
{
TaskQueue taskQueue = new TaskQueue();
SerialQueue serialQueue = new SerialQueue();
await taskQueue.Enqueue(() => SendMessage(messengerViewModel.PhoneNr, messengerViewModel.MessageBody,
messengerViewModel.ContactId, messengerViewModel.State));
//I'm not running tasks at same time, using one or other at time
await serialQueue.Enqueue(() => SendMessage(messengerViewModel.PhoneNr, messengerViewModel.MessageBody,
messengerViewModel.ContactId, messengerViewModel.State));
return Ok();
}
我该如何通过每次点击来解决问题并将任务堆叠到队列中?
services.AddSingleton<SerialQueue, SerialQueue>();
我用这种方式注入了队列,但情况仍然相同,我是不是漏掉了什么重要的东西? - Daniel Žeimo