添加任务时,为什么要创建列表的新实例?

时间:2019-04-23 12:53:46

标签: c# asp.net async-await

我有一个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每次访问任务列表时,当将任务添加到任务列表时,该列表为空,似乎每次都创建一个单独的列表实例。另外,当我以后使用另一种方法访问列表时,该列表在此处为空。

为什么会发生这种情况,而不是将每个任务都添加到同一列表实例中?

1 个答案:

答案 0 :(得分:3)

ASP.NET收到新请求时,将创建页面的新实例。这就是为什么您总是看到一个空列表的原因。

应该要做的是让按钮处理程序创建一个请求ID(例如Guid),将该请求插入可靠的队列中,然后使用该请求ID更新会话状态。因此,您有一个请求ID(字符串)列表,而不是任务列表。然后,从该队列中读取一个单独的工作进程并进行实际工作。最后,“等待”页面应轮询直到请求全部完成。