我一直在努力實現一個BackgroundWorker到我的應用程序,到目前爲止,還沒有順利。在一個新線程中,我想打開一個新的表單,該表單將包含一個進度條和一個標籤以報告進度,但是,這樣做效果不佳。當我調用ShowDialog時,應用程序不再響應。這是因爲我的代碼是從我的Form1運行的,而且我正在顯示WorkingForm?此外,這可以實施更清潔?的BackgroundWorker的ShowDialog導致應用程序停止
private void button14_Click(object sender, EventArgs e)
{
List<object> param = new List<object>();
object[] objectparams = new object[1];
objectparams[0] = null;
Opera opera = new Opera();
System.Reflection.MethodInfo clearOpera = opera.GetType().GetMethod("ClearOpera");
param.Add(clearOpera);
param.Add(opera);
param.Add(objectparams);
backgroundWorker1.RunWorkerAsync(param);
}
private void button2_Click_1(object sender, EventArgs e)
{
Browser.cancelPending = true;
}
private delegate void getnewform();
private void backgroundWorker1_DoWork(object sender, DoWorkEventArgs e)
{
mainForm main = new mainForm();
TestURLGUI4.Form1 form = (TestURLGUI4.Form1)Application.OpenForms[0];
var variab = (bool)form.Invoke(new getnewform(main.AskForConfirmation));
List<object> param = e.Argument as List<object>;
List<object> result = new List<object>();
var method = param[0] as MethodInfo;
object[] parameters = param[2] as object[];
if (parameters[0] == null)
{
result.Add(method.Invoke(param[1], null));
result.Add(false);
}
else
{
result.Add(method.Invoke(param[1], parameters));
if (parameters.Contains(true))
result.Add(true);
}
int progress = (100 * Browser.progressValue)/Browser.progressMax;
backgroundWorker1.ReportProgress(progress);
// If the BackgroundWorker.CancellationPending property is true, cancel
if (backgroundWorker1.CancellationPending)
{
Console.WriteLine("Cancelled");
Browser.cancelPending = true;
}
e.Result = result;
}
private void backgroundWorker1_ProgressChanged(object sender, ProgressChangedEventArgs e)
{
TestURLGUI4.WorkingForm form = (TestURLGUI4.WorkingForm)Application.OpenForms[1];
form.progressBar1.Value = e.ProgressPercentage;
form.label1.Text = Browser.progressValue + "/" + Browser.progressMax;
Application.DoEvents();
}
private void backgroundWorker1_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
{
List<object> param = e.Result as List<object>;
if (e.Cancelled == false && param.Contains(true))
{
Display.DisplayURLs(param[0] as SortableBindingList<URL>);
TestURLGUI4.WorkingForm form = (TestURLGUI4.WorkingForm)Application.OpenForms[1];
MessageBox.Show("Done");
}
else if (e.Cancelled == false && param.Contains(false))
{
TestURLGUI4.WorkingForm form = (TestURLGUI4.WorkingForm)Application.OpenForms[1];
MessageBox.Show("Done");
}
}
public class mainForm
{
public void AskForConfirmation()
{
TestURLGUI4.Form1 form = (TestURLGUI4.Form1)Application.OpenForms[0];
var workingForm = new TestURLGUI4.WorkingForm();
workingForm.ShowDialog(form);
workingForm.DialogResult = DialogResult.None;
}
}
編輯: 好吧,我已經根據建議更新了我的代碼,而現在,這將產生在System.Windows.Forms.dll中一個stackoverflowexception:
private void backgroundWorker1_DoWork(object sender, DoWorkEventArgs e)
{
mainForm main = new mainForm();
TestURLGUI4.Form1 form = (TestURLGUI4.Form1)Application.OpenForms[0];
List<object> param = e.Argument as List<object>;
List<object> result = new List<object>();
var method = param[0] as MethodInfo;
object[] parameters = param[2] as object[];
if (parameters[0] == null)
{
result.Add(method.Invoke(param[1], null));
result.Add(false);
}
else
{
result.Add(method.Invoke(param[1], parameters));
if (parameters.Contains(true))
result.Add(true);
}
int progress = (100 * Browser.progressValue)/Browser.progressMax;
backgroundWorker1.ReportProgress(progress);
// If the BackgroundWorker.CancellationPending property is true, cancel
if (backgroundWorker1.CancellationPending)
{
Console.WriteLine("Cancelled");
Browser.cancelPending = true;
}
e.Result = result;
}
private void backgroundWorker1_ProgressChanged(object sender, ProgressChangedEventArgs e)
{
TestURLGUI4.Form1 form1 = (TestURLGUI4.Form1)Application.OpenForms[0];
if (Application.OpenForms.Count >= 2)
{
TestURLGUI4.WorkingForm form2 = (TestURLGUI4.WorkingForm)Application.OpenForms[1];
form2.progressBar1.Value = e.ProgressPercentage;
form2.label1.Text = Browser.progressValue + "/" + Browser.progressMax;
Application.DoEvents();
}
else if(Application.OpenForms.Count == 1)
{
var workingForm = new TestURLGUI4.WorkingForm();
workingForm.ShowDialog(form1);
}
}
讓youyr生活輕鬆了許多。在您關閉線程之前進行確認,並完全消除Application.OpenForms的需求。這是一個幾乎保證的比賽,表格可能會在您獲得參考後關閉。甚至不想考慮一下你的顯式索引索引可能會在應用程序發生一些變化之後留下來。 – 2012-08-13 21:15:43
有人可以看看我更新的代碼嗎? – 2012-08-14 01:17:26