Stop the for-loop intermediate loop before it completes.

We index documents in Solr using Solrnet in asp.net C # project. We have a requirement when Solr DIH cannot be used, so we index products in specific batches on Solr using the following code:

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(); } 

With the huge size of the document, it takes a lot of time (in most cases it takes several hours) to complete the whole process, and sometimes we have a need to stop this process between manual intervention.

However, I am not sure how to stop these indexing batch loops between them until they are complete. One cycle with a large volume of documents, takes a few seconds, and then is fixed. But considering the huge no. documents when performing full indexing takes several hours, and we can not stop this process between them.

Any idea is how I can stop this process between them. I can’t understand what needs to be done here?

Please offer.

+7
c # solr
source share
2 answers

Two approaches you can take are as follows:

1 Use a global variable (this is not a good solution, although I hope for obvious reasons):

 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 Use the callback to verify whether to continue:

 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(); } } } 

The advantage of the second approach is that you separate the decision logic from the indexing logic and avoid global variables, for example, by capturing whether or not to continue inside the closure around the asynchronous call for a long process and event handler.

+5
source share

Another approach, perhaps a bit roundabout, is to create a Global.asax application file and try using a background worker, as described here . You can also see my example for 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(); } } } } } 
0
source share

All Articles