C# 如何:取消Web服务功能请求

C# 如何:取消Web服务功能请求,c#,asp.net,web-services,jquery,C#,Asp.net,Web Services,Jquery,这可能会在别处讨论,但我找不到。我有一个.NETWeb服务,它有一个函数,可以循环一个日期范围,运行计算并更新数据库中的记录。如果你给这个函数一个很长的日期范围,它可能需要相当长的时间才能完成。在这种情况下,我需要一种方法来停止这个函数 是否有一种方法可以使web服务函数调用在已标识的线程中运行,以便在需要时取消该线程?还是我想得太多或太少了?我使用带有jQuery的C#.Net网页来执行对Web服务函数的AJAX调用。任何帮助都将不胜感激。当然,你可以做到。如果您使用的是.NET 4,则可以轻

这可能会在别处讨论,但我找不到。我有一个.NETWeb服务,它有一个函数,可以循环一个日期范围,运行计算并更新数据库中的记录。如果你给这个函数一个很长的日期范围,它可能需要相当长的时间才能完成。在这种情况下,我需要一种方法来停止这个函数


是否有一种方法可以使web服务函数调用在已标识的线程中运行,以便在需要时取消该线程?还是我想得太多或太少了?我使用带有jQuery的C#.Net网页来执行对Web服务函数的AJAX调用。任何帮助都将不胜感激。

当然,你可以做到。如果您使用的是.NET 4,则可以轻松取消任务:

 CancellationTokenSource cts = new CancellationTokenSource();
 var processingTask = Task.Factory.StartNew(() =>
    {
          foreach(var item in StuffToProcess())
          {
               cts.Token.ThrowIfCancellationRequested();

               // Do your processing in a loop
          }
    });

  var cancelTask = Task.Factory.StartNew(() =>
      {
           Thread.Sleep(/* The time you want to allow before cancelling your processing */);
           cts.Cancel();
      });

   try
   {
       Task.WaitAll(processingTask, cancelTask);
   }
   catch(AggregateException ae)
   {
       ae.Flatten().Handle(x =>
          {
               if(x is OperationCanceledException)
               {
                   // Do Anything you need to do when the task was canceled.
                   return true;
               }

               // return false on any unhandled exceptions, true for handled ones
          });
   }

将Cancel()方法添加到设置状态变量的web服务中。然后,只需让长时间运行的操作定期检查此变量,并在其设置时停止(当然要有适当的保护)。

您需要了解web服务方法:

  • 启动计算(parms)它跨越长时间运行的操作并返回一个ID
  • 取消计算(ID)通过终止长时间运行的操作来取消计算

  • “长时间运行操作”的实现取决于您的服务主机(IIS、Windows服务等)。

    谁决定取消线程:调用者,或您的web服务实现(基于某个超时)?这看起来接近我想要的,但要求用户能够查看此函数的请求队列并取消特定请求。一次可能有1-20个这样的请求,我需要能够取消一个特定的请求。在这种情况下,您需要在某种共享持有者中保留对该对象的引用,而不是为其启动任务,然后您的web管理员选择调用
    cts.cancel()
    在指定的令牌上。我已经跟踪了队列对象(只是数据库中的一个条目,用于跟踪谁请求同步的日期范围)。那么,我如何捕获该线程的令牌以便将其添加到我的数据库中,以及我是否使用上面的代码取消该线程?我不能相信,由于其简单性,我竟然忽略了您的答案。但是,正如奥卡姆的剃刀所暗示的那样,最简单的答案就是最好的答案。在查看了其他回复之后,Tejs的回答建议取消我在问题中提到的线程,但是,这可能会使未提交的数据库事务延迟。所以,我更仔细地考虑了你的答案。使用您的方法,我使用“cancel”调用设置了一个状态(或会话)变量,然后在循环的下一次迭代中检查该变量,这样,任何正在进行的事务都会被提交,而不是孤立。我很高兴这有帮助。不要担心疏忽——这是结对编程的第二好方法;)这也类似于亚当的建议。我最初忽略了这些答案,因为它们很简单。但是,请看Adam的答案,了解我为什么选择它。Adam答案的主要区别在于,我认为您需要返回标识操作的ID,否则您无法支持多个客户端。如果没有ID,您将不知道在有多个运行的情况下取消哪个操作!是的,我有一个日志表,记录正在发生的迭代,我返回该迭代的id,如果单击“取消”,它会将该id传递给cancel函数,并将应用程序变量设置为该id以取消,然后在下一次迭代时,它会取消具有该id的迭代。感谢您提供的信息