我有一个asp.net应用程序,用户可以在其中按一个按钮来启动长时间运行的操作,并且可以多次执行。每次他们这样做时,我都希望将创建的任务添加到列表中,以便稍后他们想要进入下一页时,该页面在重定向之前等待列表中的所有任务完成。
我具有以下结构:
private List<Task> tasks = new List<Task>();
private SemaphoreSlim mutex = new SemaphoreSlim(1, 1);
// Simulate some work
private async Task MyWork()
{
int t = 0;
while (t < 5)
{
await Task.Delay(TimeSpan.FromSeconds(5));
t ++;
}
}
// Called in the button's eventhandler
public void DoWork()
{
mutex.Wait();
this.tasks.Add(Task.Run(() => MyWork());
mutex.Release();
}
调试时,我发现DoWork每次访问任务列表时,当将任务添加到任务列表时,该列表为空,似乎每次都创建一个单独的列表实例。另外,当我以后使用另一种方法访问列表时,该列表在此处为空。
为什么会发生这种情况,而不是将每个任务都添加到同一列表实例中?
答案 0 :(得分:3)
ASP.NET收到新请求时,将创建页面的新实例。这就是为什么您总是看到一个空列表的原因。
您应该要做的是让按钮处理程序创建一个请求ID(例如Guid),将该请求插入可靠的队列中,然后使用该请求ID更新会话状态。因此,您有一个请求ID(字符串)列表,而不是任务列表。然后,从该队列中读取一个单独的工作进程并进行实际工作。最后,“等待”页面应轮询直到请求全部完成。