如何在MVC3中使用cancellationToken?

时间:2013-05-03 10:13:26

标签: c# asp.net-mvc multithreading asp.net-mvc-3 asynchronous

我是MVC3的新手。在我的项目MVC3中,我正在使用线程导入excel        表到数据库,它完美地工作。我对以下内容有疑问,        1)如何使用CancellationToken停止线程?             - 在我的MVC#表单中,我有以下... 2个按钮名为取消和导入               分别。        2)在导入按钮提交事件我有以下代码。

    //Button Click on Import
    [HttpPost]
    public ActionResult FinalImport(FormCollection collection)
      {
            Task.Factory.StartNew(() =>
            { 
               //My Coding To Import

            } , tokenSource.Token);

            return null;
      }

    CancellationTokenSource tokenSource=new CancellationTokenSource();

    //Button Click on Cancel 
    public void CancelToken()
    {
        tokenSource.Token.ThrowIfCancellationRequested();
        tokenSource.Cancel();
      //  return null;
    }

注意:如果我单击导入按钮和运行任务,然后单击取消按钮menas什么都不会发生..如何取消线程进程的执行。  请帮我实现这个目标......

2 个答案:

答案 0 :(得分:3)

由于Web本质上是无状态环境,因此您需要某种方法将取消令牌从一个请求持久保存到另一个请求。 FinalImport和CancelToken方法是单独的请求。该应用程序将每个应用程序视为全新的,就好像之前从未见过先前的请求一样。您正在编写代码,就像它在有状态的环境中运行一样。

以下内容适用于您。

以下是高级步骤:

  • 在FinalImport方法中创建tokenSource。
  • 将令牌源添加到具有唯一键的字典中,该键将保留请求。 (假设一个声明为静态,因此它对整个应用程序是全局的。)
  • 将密钥传回浏览器。

当用户在浏览器中按下取消按钮时:

  • 让浏览器在请求中发送密钥。
  • 在CancelToken中,使用浏览器随请求发送的密钥查找字典。
  • 使用字典中的tokenSource取消任务。
  • 从字典中删除令牌。

作为任务中的最后一件事,您还应该从字典中删除令牌(否则它们只会累积起来,直到内存不足为止)

如果出于任何原因,运行Web应用程序的进程失败并且IIS必须重新启动它,那么您将丢失字典。 IIS将因各种原因重新启动您的进程,例如内存压力(例如,您可能有内存泄漏并创建了一个新的进程),或者因为它自上次重新启动以来已经过了29个小时,或者因为有很多东西。如果您正在运行Web园或Web场,则无法保证在每个请求中都返回相同的进程,因此字典可能不可用。

虽然我意识到这不是代码解决方案,但我希望这有助于更好地理解问题领域。

答案 1 :(得分:0)

最后我找到了解决方案。

1)需要将CancellationTokenSource初始化为静态。

2)需要在CancelToken方法中处理CancellationTokenSource对象tokensource    调用

public static CancellationTokenSource tokenSource; 

[HttpPost]
    public ActionResult FinalImport(FormCollection collection)
      {
            tokensource=new CancellationTokenSource();
            Task.Factory.StartNew(() =>
            { 
                 if (ts.IsCancellationRequested)
                            {
                                break;
                            }
               //My Coding To Import

            } , tokenSource.Token);

            return null;
      }



    //Button Click on Cancel 
    public void CancelToken()
    {

        tokenSource.Cancel();
        tokensource.Dispose();
    }

就是这样.. 快乐的编码.... !!!!