0

我是 MVC3 的新手。在我的项目 MVC3 中,我正在使用线程将 excel 表导入数据库,并且效果很好。我对以下内容有疑问,1)如何使用 CancellationToken 停止线程?-- 在我的 MVC# 表单中,我有以下.. 2 个按钮分别名为 Cancel 和 Import。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;
    }

注意:如果我单击导入按钮,然后在运行任务时单击取消按钮,则不会发生任何事情。如何取消线程进程的执行。请帮助我实现这一目标...

4

2 回答 2

3

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

以下内容可能对您有用。

以下是高级步骤:

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

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

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

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

如果出于任何原因,运行您的 Web 应用程序的进程失败并且 IIS 必须重新启动它,那么您将丢失您的字典。IIS 将出于各种原因重新启动您的进程,例如内存压力(例如,您可能有内存泄漏并且它会创建一个新的进程来使用),或者因为距离上次重新启动它已经 29 小时,或者因为任何数量的事情。如果您正在运行网络花园或网络农场,则不能保证每次请求都返回到相同的进程,因此字典可能不可用。

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

于 2013-05-03T23:32:28.570 回答
0

最后我找到了解决方案。

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

2)需要在CancelToken方法
调用中Dispose 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();
    }

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

于 2013-05-07T09:28:16.903 回答