我有一个简单的应用程序,它通过一个BackgroundWorker在一个单独的线程中执行一个函数,并且遇到了问题。我正在收集一个值的字符串数组,并通过ReportProgress方法将它传递回我的ReportProgress事件,我遇到了一个问题,在这个问题中,线程继续并且速度如此之快,它超过了ProgressChanged事件,并覆盖了这些值,然后才能添加到网格中。下面是我的密码..。
按钮点击事件触发我的线程..。
private void LoadButton_Click(object sender, EventArgs e)
{
if (!string.IsNullOrEmpty(WorkingPathTextBox.Text))
{
this.dataGridView1.Rows.Clear();
this.progressBar1.Visible = true;
this.LoadButton.Visible = false;
this.BrowseButton.Enabled = false;
this.WorkingPathTextBox.Enabled = false;
this.CancelBtn.Visible = true;
this.ProcessingLabel.Visible = true;
beginTime = DateTime.Now;
WorkflowCleanup wc = new WorkflowCleanup();
wc.WorkflowPath = this.WorkingPathTextBox.Text;
backgroundWorker1.RunWorkerAsync(wc);
}
}在DoWork中,它加载我工作所在的类.
private void backgroundWorker1_DoWork(object sender, DoWorkEventArgs e)
{
System.ComponentModel.BackgroundWorker worker;
worker = (System.ComponentModel.BackgroundWorker)sender;
// Get the Words object and call the main method.
WorkflowCleanup wc = (WorkflowCleanup)e.Argument;
wc.LoadAssemblies(worker, e);
wc.LoadDataDefinitions(worker, e);
wc.LoadDataDefinitionsDirty(worker, e);
wc.LoadProcesses(worker, e);
wc.LoadProcessesDirty(worker, e);
wc.LoadWorkflows(worker, e);
// wc.UpdateWorkflows(worker, e);
}WorkflowCleanup class...the ReportProgress卡在尝试/捕捉的中间,因为我不知道是什么导致了问题。因此,我在尝试中移动了它,甚至必须添加一个Thread.Sleep(100)来减慢进程,以便给ProgressChanged事件足够的时间,以便在它被覆盖之前将它添加到网格中的数据行。
namespace WorkflowMaintenance
{
public class WorkflowCleanup
{
private int errorCount = 0;
private int fixCount = 0;
public class Workflow
{
// code truncated
}
public class WorkflowAssembly
{
// code truncated
}
public class DataDefinition
{
// code truncated
}
public class CurrentState
{
public int Percentage;
public string StateString;
public List<string[]> ProcessResults;
public string[] Result;
public int ErrorCount;
public int FixCount;
}
public void LoadAssemblies(System.ComponentModel.BackgroundWorker worker, System.ComponentModel.DoWorkEventArgs e)
{
CurrentState state = new CurrentState();
fixCount = 0;
errorCount = 0;
string[] asmbfiles = System.IO.Directory.GetFiles(WorkflowPath + "\\Assemblies", "*.asmb", System.IO.SearchOption.AllDirectories);
int asmbIndex = 0;
Assemblies = new List<WorkflowAssembly>();
// Assemblies (NEW)
foreach (string asmb in asmbfiles)
{
if (worker.CancellationPending)
{
e.Cancel = true;
break;
}
else
{
//results = new List<string[]>();
asmbIndex += 1;
int percentage = (asmbIndex * 100) / asmbfiles.Length;
state.StateString = string.Format("Loading Assemblies... {0}%", percentage);
state.Percentage = percentage;
try
{
XDocument xdoc = XDocument.Load(asmb);
XElement asmbElement = xdoc.Descendants(wf + "assembly").First();
XElement asmbTypes = asmbElement.Element(wf + "types");
string asmbid = asmbElement.Attribute("id").Value;
string asmbname = asmbElement.Element(wf + "name").Value;
string asmbpath = asmbElement.Element(wf + "assemblyPath").Value;
Assemblies.Add(new WorkflowAssembly() { ID = asmbid, Name = asmbname, FileName = asmb, AssemblyPath = asmbpath, Types = asmbTypes });
//results.Add(new string[] { "SUCCESS", "ASSEMBLY PROCESSED SUCCESSFULLY", asmbname, asmbid, null, asmb });
state.Result = new string[] { "SUCCESS", "ASSEMBLY PROCESSED SUCCESSFULLY", asmbname, asmbid, null, asmb };
fixCount += 1;
//if (results != null && results.Count > 0)
//{
// state.ProcessResult = results;
//}
state.FixCount = fixCount;
state.ErrorCount = errorCount;
worker.ReportProgress(percentage, state);
Thread.Sleep(100);
}
catch (Exception)
{
// need to report the exception...
errorCount += 1;
}
finally
{
//if (results != null && results.Count > 0)
//{
// state.ProcessResult = results;
//}
//state.FixCount = fixCount;
//state.ErrorCount = errorCount;
//worker.ReportProgress(percentage, state);
}
}
}
}
}
}ProgressChanged事件..。
private void backgroundWorker1_ProgressChanged(object sender, ProgressChangedEventArgs e)
{
// This method runs on the main thread.
WorkflowCleanup.CurrentState state = (WorkflowCleanup.CurrentState)e.UserState;
this.progressBar1.Value = state.Percentage;
this.ProcessingLabel.Text = state.StateString;
this.errorLabel.Text = string.Format("Errors: {0}", state.ErrorCount);
this.fixLabel.Text = string.Format("Fixed: {0}", state.FixCount);
this.ElapsedTimeLabel.Text = string.Format("Elapsed Time: {0}", GetProgressElapsedString());
if (state.Result != null)
{
this.dataGridView1.Rows.Add(state.Result);
}
}Problem...the问题是,如果文件夹中有3个文件(名为Assembly1、Assembly2和Assembly3),网格中的输出显示这三个文件都名为Assembly3。我唯一能解决的办法就是让线睡觉。这不是一个选项,因为我必须运行这个文件夹有大约18,000个文件,必须睡眠一毫秒将永远。但是,我需要得到有效的结果。请帮助:-)
发布于 2015-02-02 21:23:53
与其在循环之外创建state对象并在每次迭代中对其进行变异,不如为每个迭代创建一个新实例。这可以通过简单地在循环中移动变量的声明来实现。
https://stackoverflow.com/questions/28286831
复制相似问题