Проблема / с возникает только с кнопкой «Пауза».
Если фоновый рабочий работает и ищет, а затем я щелкаю правый верхний X, чтобы закрыть программу посередине, все будет хорошо также после нажатия Кнопка остановки. Проблема возникает только с кнопкой «Пауза».
Вверху:
private System.Windows.Forms.Timer timer1 = new System.Windows.Forms.Timer();
private readonly Stopwatch _stopwatch = new Stopwatch();
private ManualResetEvent _isbackgroundbusy = new ManualResetEvent(false);
В событии нажатия кнопки «Пуск»:
timer1.Start();
if (!backgroundWorker1.IsBusy)
{
SetWorkerMode(true);
backgroundWorker1.RunWorkerAsync();
}
Функция SetWorkerMode:
private void SetWorkerMode(bool running)
{
if (running)
{
stopButton.Enabled = true;
timer1.Enabled = true;
pauseresumeButton.Text = "Pause";
_isbackgroundbusy.Set();
}
else
{
stopButton.Enabled = false;
timer1.Enabled = false;
pauseresumeButton.Text = "Resume";
_isbackgroundbusy.Reset();
}
}
In backgroundworker1 dowork:
private void backgroundWorker1_DoWork(object sender, DoWorkEventArgs e)
{
BackgroundWorker worker = sender as BackgroundWorker;
_stopwatch.Restart();
string[] values = textBoxSearchBox.Text.Split(new string[] { ",," }, StringSplitOptions.None);
DirSearch(textBoxRootDirectory.Text, textBoxSetFileExtensions.Text, values, worker, e);
_stopwatch.Stop();
}
В backgroundworker1 завершено:
private void backgroundWorker1_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
{
if (e.Cancelled == true)
{
_stopwatch.Stop();
timer1.Stop();
}
if (e.Error != null)
{
}
else
{
_stopwatch.Stop();
timer1.Stop();
mCompleted = true;
if (ListViewCostumControl.lvnf.Items.Count > 0)
{
listviewcostumcontrolListItems = ListViewCostumControl.lvnf.Items.Cast<ListViewItem>()
.Select(item => item.Text)
.ToList();
}
if (mClosePending) this.Close();
}
}
The OnFormClosing:
bool mCompleted = false;
bool mClosePending = false;
protected override void OnFormClosing(FormClosingEventArgs e)
{
if (!mCompleted && backgroundWorker1.IsBusy)
{
backgroundWorker1.CancelAsync();
this.Enabled = false;
e.Cancel = true;
mClosePending = true;
return;
}
base.OnFormClosing(e);
}
И пауза Событие нажатия кнопки:
private void pauseresumeButton_Click(object sender, EventArgs e)
{
SetWorkerMode(pauseresumeButton.Text == "Resume");
}
Первая проблема заключается в том, что когда я нажимаю кнопку паузы и фоновый рабочий процесс работает, требуется время, чтобы приостановить действие. Иногда секунду или две, иногда 10-20 секунд кажется, что нужно закончить sh сначала что-то, а затем сделать паузу, а не делать паузу, когда я нажимаю кнопку паузы.
Вторая проблема возникает после нажатия кнопки паузы и если она приостановлена или еще не остановлена, а затем щелкнув форму вверху справа X, чтобы закрыть программу, вся программа зависает.
Если нужно, добавлю еще и код поискового ядра. Когда backgroundworker работает, программа выполняет рекурсивный поиск.
Функция DirSearch:
int numberofdirs = 0;
void DirSearch(string rootDirectory, string filesExtension, string[] textToSearch, BackgroundWorker worker, DoWorkEventArgs e)
{
List<string> filePathList = new List<string>();
int numberoffiles = 0;
try
{
filePathList = SearchingCore.SearchAccessibleFilesNoDistinct(rootDirectory, null, worker, e,_isbackgroundbusy,
textBoxSetFileExtensions, lblretrievedfiles,lblrestrictedfiles).ToList();
}
catch (Exception err)
{
}
lblphases.Invoke((MethodInvoker)delegate
{
lblphases.Text = "Phase 2: Searching in files";
});
MyProgress myp = new MyProgress();
myp.Report4 = filePathList.Count.ToString();
foreach (string file in filePathList)
{
try
{
var tempFR = File.ReadAllText(file);
var f = Path.GetFileName(file);
_isbackgroundbusy.WaitOne();
if (worker.CancellationPending == true)
{
e.Cancel = true;
return;
}
bool reportedFile = false;
for (int i = 0; i < textToSearch.Length; i++)
{
if (tempFR.IndexOf(textToSearch[i], StringComparison.InvariantCultureIgnoreCase) >= 0)
{
if (!reportedFile)
{
numberoffiles++;
myp.Report1 = file;
myp.Report2 = numberoffiles.ToString();
myp.Report3 = textToSearch[i];
myp.Report5 = FindWordsWithCountRegex(tempFR, textToSearch).ToString();
backgroundWorker1.ReportProgress(0, myp);
reportedFile = true;
}
}
}
numberofdirs++;
lblsearchedfiles.Invoke((MethodInvoker)delegate
{
});
}
catch (Exception err)
{
}
}
}
My Progress class:
public class MyProgress
{
public string Report1 { get; set; }
public string Report2 { get; set; }
public string Report3 { get; set; }
public string Report4 { get; set; }
public string Report5 { get; set; }
}
Backgroundworker1 progresschange событие:
private void backgroundWorker1_ProgressChanged(object sender, ProgressChangedEventArgs e)
{
MyProgress mypro = (MyProgress)e.UserState;
ListViewCostumControl.lvnf.Items.Add(mypro.Report1);
lblfileswithresults.Text = mypro.Report2;
lblresultsinfiles.Text = mypro.Report5;
if (ListViewCostumControl.lvnf.Items.Count > 9)
textBoxSearchInResults.Enabled = true;
}
И, наконец, класс SearchingCore:
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using System.Windows.Forms;
namespace Search_Text_In_Files
{
class SearchingCore
{
private static string restrictedFile = "";
private static List<string> restrictedFiles = new List<string>();
private static int numberofrestrictedFiles = 0;
private static int numberoffiles = 0;
public static IEnumerable<string> SearchAccessibleFilesNoDistinct(string root, List<string> files,
BackgroundWorker worker, DoWorkEventArgs e,
ManualResetEvent _isbackgroundbusy, TextBox textBoxSetFileExtensions,
Label lblretrievedfiles, Label lblrestrictedfiles)
{
_isbackgroundbusy.WaitOne();
if (files == null)
files = new List<string>();
try
{
if (Directory.Exists(root))
{
try
{
foreach (var file in Directory.EnumerateFiles(root))
{
try
{
if (worker.CancellationPending == true)
{
e.Cancel = true;
return files;
}
restrictedFile = file;
string ext = Path.GetExtension(file);
if (!files.Contains(file) && ext == textBoxSetFileExtensions.Text)
{
files.Add(file);
}
numberoffiles++;
lblretrievedfiles.Invoke((MethodInvoker)delegate
{
lblretrievedfiles.Text = numberoffiles.ToString();
lblretrievedfiles.Visible = true;
});
}
catch
{
string jj = "";
}
}
}
catch (Exception err)
{
string gg = "";
}
foreach (var subDir in Directory.EnumerateDirectories(root))
{
if (worker.CancellationPending == true)
{
e.Cancel = true;
return files;
}
try
{
SearchAccessibleFilesNoDistinct(subDir, files, worker, e
,_isbackgroundbusy, textBoxSetFileExtensions,lblretrievedfiles,
lblrestrictedfiles);
}
catch (UnauthorizedAccessException)
{
restrictedFiles.Add(restrictedFile);
numberofrestrictedFiles++;
lblrestrictedfiles.Invoke((MethodInvoker)delegate
{
lblrestrictedfiles.Text = numberofrestrictedFiles.ToString();
lblrestrictedfiles.Visible = true;
});
continue;
}
}
}
}
catch(Exception err)
{
string rr = "";
}
return files;
}
}
}
Это немного длинный код, но все связано. Я старался максимально сократить код. Я добавил остальной код внизу, если он не нужен, но я думаю, что он нужен для решения проблемы, поскольку все подключено.