后台Worker不会在RunWorkerAsync()之后启动
本文关键字:之后 启动 RunWorkerAsync Worker 后台 | 更新日期: 2023-09-27 18:03:27
c#新手-我从网上找到的一个示例项目中拼凑了一些代码部分,这与我想要完成的接近-它拒绝以相同的方式行事。到目前为止,我学到了很多东西,也做了很多调整,但这篇文章仍然让我困惑,我在网上找不到任何完全相同的东西。在示例程序中,backgroundWorker.RunWorkerAsync();直接跳到节目的下一部分。在我的代码中,它不会。我把休息在许多不同的地方,它总是停止,似乎挂在RunWorkerAsync()。我认为部分问题在于示例程序的原作者使用后台工作器的方式与我在网上看到的大多数示例不一致……但当我单独运行它时,它在示例程序中是有效的。我错过了什么?
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;
using System.IO;
using System.Text.RegularExpressions;
namespace DIPUtil
{
public partial class DIPform : Form
{
#region Fields
private string outputDirectory;
protected string findWhatString = "BEGIN";
protected string replaceWithText = "FANOODLE";
#endregion
#region Background
BackgroundWorker worker = new BackgroundWorker();
/// <summary>
/// Executes the main find and replace operation.
/// </summary>
/// <param name="worker">The BackgroundWorker object.</param>
/// <returns>The number of files affected by the replace operation.</returns>
private int DoFindReplace(BackgroundWorker worker)
{
//Initialize the affected count variable
int filesAffectedCount = 0;
//Initialize the counter
int counter = 0;
//Get all XML files in the directory
string[] filesInDirectory = Directory.GetFiles(outputDirectory, "*.txt");
//Initialize total file count
int totalFiles = filesInDirectory.GetLength(0);
//Analyze each file in the directory
foreach (string file in filesInDirectory)
{
//Perform find and replace operation
if (FindAndReplace(file))
{
//The file was changed so increment variable
filesAffectedCount++;
}
//Increment the counter
counter++;
//Report progress
worker.ReportProgress((int)((counter / totalFiles) * 100.00));
}
//Return the total number of files changed
return filesAffectedCount;
}
#endregion
#region FindAndReplace
/// <summary>
/// Performs the find and replace operation on a file.
/// </summary>
/// <param name="file">The path of the file to operate on.</param>
/// <returns>A value indicating if the file has changed.</returns>
private bool FindAndReplace(string file)
{
//holds the content of the file
string content = string.Empty;
//Create a new object to read a file
using (StreamReader sr = new StreamReader(file))
{
//Read the file into the string variable.
content = sr.ReadToEnd();
}
//Get search text
string searchText = GetSearchText(findWhatString);
//Look for a match
if (Regex.IsMatch(content, searchText))
{
//Replace the text
string newText = Regex.Replace(content, searchText, replaceWithText);
//Create a new object to write a file
using (StreamWriter sw = new StreamWriter(file))
{
//Write the updated file
sw.Write(newText);
}
//A match was found and replaced
return true;
}
//No match found and replaced
return false;
}
#endregion
#region Various
/// <summary>
/// Gets the text to find based on the selected options.
/// </summary>
/// <param name="textToFind">The text to find in the file.</param>
/// <returns>The text to search for.</returns>
private string GetSearchText(string textToFind)
{
//Copy the text to find into the search text variable
//Make the text regex safe
string searchText = Regex.Escape(findWhatString);
return searchText;
}
/// <summary>
/// Sets the properties of the controls prior to beginning the download.
/// </summary>
private void InitializeProcess()
{
//Get sources
outputDirectory = txtDirectory.Text;
//Set properties for controls affected when replacing
statuslabel.Text = "Working...";
progbar.Value = 0;
progbar.Visible = true;
btnprocess.Enabled = false;
btncancel.Enabled = true;
//Begin downloading files in background
backgroundWorker.RunWorkerAsync();
}
/// <summary>
/// Sets the properties of the controls after the download has completed.
/// </summary>
private void DeinitializeProcess()
{
//Set properties for controls affected when operating
statuslabel.Text = "Ready";
progbar.Visible = false;
btnprocess.Enabled = true;
btncancel.Enabled = false;
}
/// <summary>
/// Displays the directory browser dialog.
/// </summary>
private void BrowseDirectory()
{
//Create a new folder browser object
FolderBrowserDialog browser = new FolderBrowserDialog();
//Show the dialog
if (browser.ShowDialog(this) == DialogResult.OK)
{
//Set the selected path
txtDirectory.Text = browser.SelectedPath;
}
}
/// <summary>
/// Validates that the user input is complete.
/// </summary>
/// <returns>A value indicating if the user input is complete.</returns>
private bool InputIsValid()
{
//Set the error flag to false
bool isError = false;
//Clear all errors
errorProvider.Clear();
//Validate the directory name
if (string.IsNullOrEmpty(txtDirectory.Text))
{
errorProvider.SetError(txtDirectory, "This is a required field.");
isError = true;
}
else
{
//check to make sure the directory is valid
if (Directory.Exists(txtDirectory.Text) == false)
{
errorProvider.SetError(txtDirectory, "The selected directory does not exist.");
isError = true;
}
}
//Return a value indicating if the input is valid
if (isError)
return false;
else
return true;
}
#endregion
#region Events
private void backgroundWorker_DoWork(object sender, DoWorkEventArgs e)
{
//Create a work object and initialize
BackgroundWorker worker = sender as BackgroundWorker;
//Run the find and replace operation and store total files affected in the result property
e.Result = (int)DoFindReplace(worker);
}
private void backgroundWorker_ProgressChanged(object sender, ProgressChangedEventArgs e)
{
//Update the prog bar
progbar.Value = e.ProgressPercentage;
}
private void backgroundWorker_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
{
//The background operation is done
DeinitializeProcess();
//Perform final operations
if (e.Error != null)
MessageBox.Show(this, e.Error.Message, "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
else if (e.Cancelled)
MessageBox.Show(this, "The operation was ended by the user.", "Cancelled.", MessageBoxButtons.OK, MessageBoxIcon.Error);
else
MessageBox.Show(this, string.Format("{0} files were updated by the operation.", e.Result.ToString()), "Replace Complete", MessageBoxButtons.OK, MessageBoxIcon.Information);
}
public DIPform()
{
InitializeComponent();
}
private void DIPform_Load(object sender, EventArgs e)
{
}
private void btnprocess_Click(object sender, EventArgs e)
{
//Verify input is ok
if (InputIsValid())
InitializeProcess();
}
private void btncancel_Click(object sender, EventArgs e)
{
}
//private void linkbrowse_LinkClicked(object sender, LinkLabelLinkClickedEventArgs e)
// {
//Select a directory to output files
// BrowseDirectory();
//}
private void linkbrowse_LinkClicked_1(object sender, LinkLabelLinkClickedEventArgs e)
{
//Select a directory to output files
BrowseDirectory();
}
#endregion
}
}
当您调用RunWorkerAsync()
时,将引发事件DoWork
。当发生这种情况时,将执行添加到此事件的方法:
backgroundWorker1.DoWork += new DoWorkEventHandler(backgroundWorker1_DoWork);
private void backgroundWorker1_DoWork(object sender, DoWorkEventArgs e) {/...}
检查你的设计器,看看它是否连接正确。
查看更多信息:
BackGround Worker Class.
你想要什么?如果您通过设计器将后台工作器放在表单上,并连接事件处理程序,然后通过创建一个新引用(就像您所做的那样)手动为其分配一个新引用,变量内部引用的值将发生变化,并且现在变量内部有另一个引用,就像事件侦听器先前附加到的那样。你不需要创建一个新的BackroundWorker,如果你用设计器把它拖到窗体上。如果你做所有的代码,那么你需要实例化,手动附加监听器,等等....两种方法都是部分排他性的处理方法,你可以混合它们,只有当你有一个清晰的观点…