[英]Queuing tasks in asp.net core
例如功能有20个用户,他们几乎一次点击发送按钮,因此发送队列和第一个用户消息的方法发送并收到响应,在第二个三分之后,依此类推。 用户不会与其他人聊天,但设备响应非常快
所以我正在尝试排队发送Message的Task。
我找到了使用任务队列的代码示例,如示例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 )时,任务仍然会同时执行并相互中断。
例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();
}
如何通过每次点击解决问题和堆栈任务排队?
您的问题是每次都创建一个新的TaskQueue
和SerialQueue
。 因此,每次用户单击/调用PostMessage
都会创建一个新队列,该任务是队列中的第一个任务并直接执行。
您应该使用静态/单例队列,以便每次单击/调用对同一队列对象起作用。
但是,当您跨多个服务器扩展Web应用程序时,这会产生问题。 为此,您应该使用(例如)Azure Queue Storage与Azure Functions结合使用的内容。
public void ConfigureServices(IServiceCollection services)
{
services.AddSingleton<TaskQueue>();
services.AddSingleton<SerialQueue>();
// the rest
}
[HttpPost(Name = "add-message")]
public async Task<IActionResult> PostMessage(
[FromBody] MessengerViewModel messengerViewModel,
[FromServices] TaskQueue taskQueue,
[FromServices] SerialQueue 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();
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.