2015-11-25 34 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(); 
       } 
      } 
     } 
    } 
} 
相關問題