【发布时间】:2012-08-17 19:26:42
【问题描述】:
我有一个窗体 (Form1),当单击一个按钮时,我想在线程中打开另一个窗体 (form2)。
我想在线程中打开它,因为当它启动时,我会读取它并为 10k+ 行长文件的语法着色,这大约需要 5 或 6 分钟。
我的问题是我不知道“正确”的做法。我已经找到了如何做到这一点并且它工作正常,但我希望能够有一个进度条告诉我 Form2 的处理进度。 (可能带有后台工作对象)
这是我的布局
Form1 有一个 RichTextBoxes 和一个按钮,单击该按钮,它会在另一个线程中打开一个表单,为 form1 的 rtb 中的文本着色。
Form2 也有一个 Rtb,这个 rtb 有一个 ProcessAllLines 方法,它处理行并完成我想在另一个线程中完成的工作。
这就是我认为我遇到困难的原因。当表单等待加载时,文本框正在执行工作。
这是我打开 Form2 的方法:
private void button1_Click(object sender, EventArgs e)
{
ColoringThread colorer = new ColoringThread(this.m_bruteView.Text);
Thread theThread = new Thread(new ThreadStart(colorer.OpenColorWindow));
theThread.Start();
}
public class ColoringThread
{
string text;
public ColoringThread(string initText)
{
text = initText;
}
public void OpenColorWindow()
{
Form2 form2 = new Form2(text);
form2.ShowDialog();
}
};
这是 form2 的工作原理:
string initText;
public Form2(string initTextInput)
{
initText = initTextInput;
InitializeComponent();
}
private void InitializeComponent()
{
this.m_ComplexSyntaxer = new ComplexSyntaxer.ComplexSyntaxer();
this.SuspendLayout();
//
// m_ComplexSyntaxer
//
this.m_ComplexSyntaxer.Dock = System.Windows.Forms.DockStyle.Fill;
this.m_ComplexSyntaxer.Location = new System.Drawing.Point(0, 0);
this.m_ComplexSyntaxer.Name = "m_ComplexSyntaxer";
this.m_ComplexSyntaxer.Size = new System.Drawing.Size(292, 273);
this.m_ComplexSyntaxer.TabIndex = 0;
this.m_ComplexSyntaxer.Text = initText;
this.m_ComplexSyntaxer.WordWrap = false;
// THIS LINE DOES THE WORK
this.m_ComplexSyntaxer.ProcessAllLines();
//
// Form2
//
this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
this.ClientSize = new System.Drawing.Size(292, 273);
this.Controls.Add(this.m_ComplexSyntaxer);
this.Name = "Form2";
this.Text = "Form2";
this.ResumeLayout(false);
}
这里是完成工作的地方:
public void ProcessAllLines()
{
int nStartPos = 0;
int i = 0;
int nOriginalPos = SelectionStart;
while (i < Lines.Length)
{
m_strLine = Lines[i];
m_nLineStart = nStartPos;
m_nLineEnd = m_nLineStart + m_strLine.Length;
m_nLineLength = m_nLineEnd - m_nLineStart;
ProcessLine(); // This colors the current line!
i++;
nStartPos += m_strLine.Length + 1;
}
SelectionStart = nOriginalPos;
}
Sooo,打开这个 form2 并让它向 Form1 报告进度以显示给用户的“正确”方式是什么? (我之所以问,是因为有人告诉我这不是正确的做法,我显然会受到“跨线程”违规?)
【问题讨论】:
-
“我想在一个线程中打开另一个窗体(form2)。” - 不要(尝试)那样做。
-
按照 John Skeet 的建议去做,您可以在一个表单/线程中完成所有这些操作。无需 MDI 表单
-
这里有一个很棒的链接,它将向您展示如何报告进度msdn.microsoft.com/en-us/library/…
标签: c# winforms multithreading