2015-11-25 37 views
7

我们使用asp.net c#项目中的Solrnet将文档索引到Solr中。我们正在要求在无法使用Solr的DIH,所以我们用下面的代码索引的产品在某些批次到Solr:在完成之前停止for-loop之间

decimal cycleCount = ProductCount/batchSize; 
for (int i = 0; i <= Math.Round(cycleCount); i++) 
{  
    var Products = Products(batchSize, languageId, storeId).ToList(); 
    solrCustomWorker.Add(solrProducts); 
    solrCustomWorker.Commit(); 
} 

有了巨大的文件的大小,它需要大量的时间(大多数的时候,它需要几小时)来完成整个过程,有时我们需要通过人工干预来中止这个过程。

但是,我不知道如何在完成之前停止这个索引批处理循环。具有大批量文档的单个循环需要几秒钟才能完成,然后提交。但考虑到巨大的不。的文件,而执行完整的索引需要几个小时,我们无法停止这个过程。

任何想法 - 我怎样才能停止这个过程之间..我无法弄清楚这里应该做什么?

请建议。

您可以在这里
+0

尝试读取http://www.davepaquette.com/archive/2015/07/19/cancelling-long-running-queries-in-asp-net- mvc-and-web-api.aspx 我希望这会有所帮助 – gabba

+2

跟踪一个布尔“运行”。将运行设置为false,然后在每个循环中检查它:if(!running)break; – dannymc18

回答

5

有两种方法:

1使用全局变量(这不是一个很好的解决方案,虽然,希望出于显而易见的原因):

public static bool KeepRunning; 

... 

for (int i = 0; i <= Math.Round(cycleCount); i++) 
{ 
    if (KeepRunning) 
    {  
     var Products = Products(batchSize, languageId, storeId).ToList(); 
     solrCustomWorker.Add(solrProducts); 
     solrCustomWorker.Commit(); 
    } 
} 

2使用一个回调来检查是否保持运行:

public void SomeMethod(Func<bool> keepRunning) 
{ 
    for (int i = 0; i <= Math.Round(cycleCount); i++) 
    { 
     if (keepRunning()) 
     {  
      var Products = Products(batchSize, languageId, storeId).ToList(); 
      solrCustomWorker.Add(solrProducts); 
      solrCustomWorker.Commit(); 
     } 
    } 
} 

第二种方法的好处是,你解耦索引逻辑的决策逻辑,避免全局变量,例如,通过捕捉是否继续运行或不在一个闭包内围绕对长时间运行的进程和事件处理程序的异步调用。

0

另一种方法,或许有点迂回,就是要创建一个应用程序文件“的Global.asax”并尝试使用后台工作描述here。您还可以看看我的例子为的WinForms here

using System; 
using System.Collections.Generic; 
using System.ComponentModel; 
using System.Linq; 
using System.Threading; 
using System.Web; 
using System.Web.Security; 
using System.Web.SessionState; 

namespace AspNetBackgroundProcess 
{ 
    public static BackgroundWorker worker = new BackgroundWorker() 
    public static bool stopWorker = false; 

    public class Global : System.Web.HttpApplication 
    { 
     protected void Application_Start(object sender, EventArgs e) 
     { 
      worker.DoWork += new DoWorkEventHandler(DoWork); 
      worker.WorkerReportsProgress = true; 
      worker.WorkerSupportsCancellation = true; 
      worker.RunWorkerCompleted += new RunWorkerCompletedEventHandler(WorkerCompleted); 
      // Calling the DoWork Method Asynchronously 
      worker.RunWorkerAsync(); 
     } 

     protected void Application_End(object sender, EventArgs e) 
     { 
      if (worker != null) 
       worker.CancelAsync(); 
     } 

     //Start Process 
     private void button1_Click(object sender, EventArgs e) 
     { 
      worker.RunWorkerAsync(); 
     } 

     //Cancel Process 
     private void button2_Click(object sender, EventArgs e) 
     { 
      //Check if background worker is doing anything and send a cancellation if it is 
      if (worker.IsBusy) 
      { 
       worker.CancelAsync(); 
      } 

     } 

     private static void DoWork(object sender, DoWorkEventArgs e) 
     { 
      decimal cycleCount = ProductCount/batchSize; //Depending on where you get these variables, you might consider moving this to the class level along with the other variable declarations 
      for (int i = 0; i <= Math.Round(cycleCount); i++) 
      { 
       //Check if there is a request to cancel the process 
       if (worker.CancellationPending) 
       { 
        e.Cancel = true; 
        worker.ReportProgress(0); 
        return; 
       } 


       var Products = Products(batchSize, languageId, storeId).ToList(); 
       solrCustomWorker.Add(solrProducts); 
       solrCustomWorker.Commit(); 
      } 
     } 
     private static void WorkerCompleted(object sender, RunWorkerCompletedEventArgs e) 
     { 
      BackgroundWorker worker = sender as BackgroundWorker; 
      if (worker != null) 
      { 
       System.Threading.Thread.Sleep(3000); 
       if (!stopWorker) 
       { 
        worker.RunWorkerAsync(); 
       } 
       else 
       { 
        while (stopWorker) 
        { 
         Thread.Sleep(6000); 
        } 
        worker.RunWorkerAsync(); 
       } 
      } 
     } 
    } 
} 
相关问题