跨线程操作?
Cross-Thread Operation?
第一次我什至不确定 C# Cross-Thread Operation
是什么,所以看到这条调试消息从一开始就让我大吃一惊 - Cross-thread operation not valid: Control 'panel1' accessed from a thread other than the thread it was created on.
我只是想写一个文本框来显示我的程序的进度。 Thread.Sleep()
为简洁起见,在下面的代码中使用。当我的代码到达 panel1.Controls.Add(txt);
行时,我收到了调试消息 这是完整的代码:
namespace WindowsFormsApplication1
{
public partial class Form1 : Form
{
private DateTime now = DateTime.Now;
private int i = 0;
TextBox txt = new TextBox();
public Form1()
{
InitializeComponent();
backgroundWorker1.WorkerReportsProgress = true;
backgroundWorker1.WorkerSupportsCancellation = false;
backgroundWorker1.DoWork += new DoWorkEventHandler(backgroundWorker1_DoWork);
backgroundWorker1.ProgressChanged += new ProgressChangedEventHandler(backgroundWorker1_ProgressChanged);
}
private void button1_Click(object sender, EventArgs e)
{
backgroundWorker1.RunWorkerAsync();
}
private void backgroundWorker1_DoWork(object sender, DoWorkEventArgs e)
{
panel1.Controls.Add(txt);
MethodOne();
MethodTwo();
}
private void backgroundWorker1_ProgressChanged(object sender, ProgressChangedEventArgs e)
{
progressBar1.Value = e.ProgressPercentage;
}
private void MethodOne()
{
txt.Text = "MethodOne Process Has Begun....." + now;
Thread.Sleep(100);
txt.Text = "MethodOne Process Has Finished....." + now;
}
private void MethodTwo()
{
txt.Text = "MethodTwo Process Has Begun....." + now;
Thread.Sleep(100);
txt.Text = "MethodTwo Has Finished....." + now;
}
}
}
如果我需要提供更多详细信息或有关如何设置我的 windows 表单的更多信息,请告诉我。
来自不同线程的 UI 上发生的操作需要称为 Invoke 的特殊编组过程。如果您不使用来自其他线程的调用,则会发生错误。
您无法直接从 BackgroundWorker 线程访问 UI 控件。 UI 控件位于单独的线程上,因此出现错误。这是不允许的:
private void backgroundWorker1_DoWork(object sender, DoWorkEventArgs e)
{
panel1.Controls.Add(txt);
...
}
BackgroundWorker 允许您传递一个数字(通常代表百分比),然后返回另一个对象(它可以是任何东西,例如您的文本)。我推荐的是:
private void backgroundWorker1_DoWork(object sender, DoWorkEventArgs e)
{
var bgw = (BackgroundWorker)sender;
bgw.ReportProgress(33, "MethodOne Process Has Begun.....");
MethodOne();
bgw.ReportProgress(66, "MethodTwo Process Has Begun.....");
MethodTwo();
bgw.ReportProgress(100, "All Processes Finished.");
}
private void backgroundWorker1_ProgressChanged(object sender, ProgressChangedEventArgs e)
{
progressBar1.Value = e.ProgressPercentage;
var statusMessage = e.UserState.ToString();
// Display statusMessage in an appropriate control, i.e. a Label
}
第一次我什至不确定 C# Cross-Thread Operation
是什么,所以看到这条调试消息从一开始就让我大吃一惊 - Cross-thread operation not valid: Control 'panel1' accessed from a thread other than the thread it was created on.
我只是想写一个文本框来显示我的程序的进度。 Thread.Sleep()
为简洁起见,在下面的代码中使用。当我的代码到达 panel1.Controls.Add(txt);
行时,我收到了调试消息 这是完整的代码:
namespace WindowsFormsApplication1
{
public partial class Form1 : Form
{
private DateTime now = DateTime.Now;
private int i = 0;
TextBox txt = new TextBox();
public Form1()
{
InitializeComponent();
backgroundWorker1.WorkerReportsProgress = true;
backgroundWorker1.WorkerSupportsCancellation = false;
backgroundWorker1.DoWork += new DoWorkEventHandler(backgroundWorker1_DoWork);
backgroundWorker1.ProgressChanged += new ProgressChangedEventHandler(backgroundWorker1_ProgressChanged);
}
private void button1_Click(object sender, EventArgs e)
{
backgroundWorker1.RunWorkerAsync();
}
private void backgroundWorker1_DoWork(object sender, DoWorkEventArgs e)
{
panel1.Controls.Add(txt);
MethodOne();
MethodTwo();
}
private void backgroundWorker1_ProgressChanged(object sender, ProgressChangedEventArgs e)
{
progressBar1.Value = e.ProgressPercentage;
}
private void MethodOne()
{
txt.Text = "MethodOne Process Has Begun....." + now;
Thread.Sleep(100);
txt.Text = "MethodOne Process Has Finished....." + now;
}
private void MethodTwo()
{
txt.Text = "MethodTwo Process Has Begun....." + now;
Thread.Sleep(100);
txt.Text = "MethodTwo Has Finished....." + now;
}
}
}
如果我需要提供更多详细信息或有关如何设置我的 windows 表单的更多信息,请告诉我。
来自不同线程的 UI 上发生的操作需要称为 Invoke 的特殊编组过程。如果您不使用来自其他线程的调用,则会发生错误。
您无法直接从 BackgroundWorker 线程访问 UI 控件。 UI 控件位于单独的线程上,因此出现错误。这是不允许的:
private void backgroundWorker1_DoWork(object sender, DoWorkEventArgs e)
{
panel1.Controls.Add(txt);
...
}
BackgroundWorker 允许您传递一个数字(通常代表百分比),然后返回另一个对象(它可以是任何东西,例如您的文本)。我推荐的是:
private void backgroundWorker1_DoWork(object sender, DoWorkEventArgs e)
{
var bgw = (BackgroundWorker)sender;
bgw.ReportProgress(33, "MethodOne Process Has Begun.....");
MethodOne();
bgw.ReportProgress(66, "MethodTwo Process Has Begun.....");
MethodTwo();
bgw.ReportProgress(100, "All Processes Finished.");
}
private void backgroundWorker1_ProgressChanged(object sender, ProgressChangedEventArgs e)
{
progressBar1.Value = e.ProgressPercentage;
var statusMessage = e.UserState.ToString();
// Display statusMessage in an appropriate control, i.e. a Label
}