【问题标题】:Queueing async Task Operations?排队异步任务操作?
【发布时间】:2013-01-16 13:57:59
【问题描述】:

我有一个 asp.net Web 应用程序,并且在一个表单中我使用异步进程。

Task.Run(async () =>
            {
                foreach (ListItem item in cbListFaculties.Items)
                {
                    if (item.Selected)
                    {
                        service.FinishSyncDepartment(actionId, item.Value);
                    }
                }
            });

但我想做的是,如果任务已经启动并且用户再次点击该页面,我想说,该任务还没有停止,所以你不能继续。

我该如何解决这个问题?有什么想法吗?

谢谢。

【问题讨论】:

  • 通过使用静态变量/会话变量等共享资源来同步多个页面请求?
  • 要详细说明 sll 所说的内容,在会话状态变量或其他一些持久性形式中,设置一个表示进程已开始的标志,然后开始该进程,完成后重置该标志。当用户来到页面时,检查标志。如果已设置,请警告他们该进程当前正在运行。那个时候,你可以做任何事情。您可以每隔几秒钟重新加载一次,直到标志被重置,或者将它们发送到另一个页面,等等......
  • Task 的引用是否有效,或者您重新加载了完整的页面并丢失了对任务的引用?如果是这样,那么您可能需要保存对 Task 的引用以便以后使用它。为此,您可以(例如)将任务声明和启动移动到另一个不依赖于您的页面的类。例如使用一些静态类,以便在页面重新加载后任务也将在那里。

标签: c# asp.net multitasking


【解决方案1】:

您可以创建Task 对象(而不是立即运行它)并使用IsCompleted property 检查它是否已完成。或者您可以使用一些线程安全对象(静态字段)来标记该任务正忙。

如果您需要任务在页面重新加载期间继续存在 - 您必须以某种方式保存对 Task 对象的引用(cookie、会话、静态变量、视图状态、缓存、数据库......)

【讨论】:

    【解决方案2】:

    您应该在 Code Behind 中保留对任务的引用,所以如果 Task 没有被释放,那么任务还没有完成。

    【讨论】:

    • 一旦响应发送到客户端,代码隐藏页面引用就会被销毁。例如,当用户点击刷新时,通常会在服务器上创建一个新的 Page 实例,因此 Task 引用会丢失。
    • @HonzaBrestan 是的,CodeBehind 已被销毁,但他可以保留 Session 或 ViewState 中的引用。
    • ViewState 被序列化并发送到客户端。您几乎无法通过参考来做到这一点。使用 session 是可能的,但我认为这是一个坏主意 - Session 可以随时刷新,它也可能需要序列化(例如,当存储在 DB 或会话服务器上时)
    【解决方案3】:

    像 0x49D1 写的那样做,但是把任务对象放在会话中,不要在网络上使用静态字段。

    【讨论】:

      猜你喜欢
      • 2019-02-14
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-08-24
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多