我有一个带有自定义进度条的自定义表单,在主类(主线程)中生成。然后我生成一个线程并发送一个ThreadStart函数。此线程启动函数应更新自定义控件中的进度条,但不是。:
class MyClass
{
......
//Custom form with progress bar
public CustomFormWithProgressBar statusScreen = new CustomFormWithProgressBar(0);
//thread to use
private Thread myThread;
.....
//Linked to a button to trigger the update procedure.
void ButtonPressEvent(.......)
{
//create a sub thread to run the work and handle the UI updates to the progress bar
myThread = new Thread(new ThreadStart(ThreadFunction));
myThread.Start();
}
.....
//The function that gets called when the thread runs
public void ThreadFunction()
{
//MyThreadClass myThreadClassObject = new MyThreadClass(this);
//myThreadClassObject.Run();
statusScreen.ShowStatusScreen();
for (int i = 0; i < 100; i++ )
{
statusScreen .SetProgressPercentage(i);
Thread.Sleep(20);
}
statusScreen.CloseStatusScreen();
}
现在我的statusScreen表单只是坐着而什么都不做。没有更新。但我已经确认子线程确实已创建,而我在ThreadFunction中,我在新线程上运行。通过visual studio中的Thread窗口确定这一点。
为什么我的状态屏幕进度百分比更新未显示?如何获取我的更新以将新值推送到进度屏幕并让它显示为现场?
请注意,发送到状态屏幕功能的整数值表示完成百分比。 Thread.Sleep只是为了查看更新是否/何时发生。
请注意,这不是重新绘图问题。当进度百分比传递到自定义进度条
时,我会调用Invalidate答案 0 :(得分:2)
您无法从其他线程更新控件。
正确的方法 - 将BackgroundWorker用于您的目的。 另一种方式(几乎正确的方式) - 使用Control.Invoke方法。 还有一个几乎正确的方法 - 使用SynchronizationContext。
但是你可以选择一个黑暗的力量并使用CheckForIllegalCrossThreadCalls - Control类的静态属性并将其设置为false。
答案 1 :(得分:1)
由于您的进度条位于UI /主线程上,因此您的线程无法修改它而不会导致交叉线程引用异常。您应该调用主线程的操作。
示例:
// in your thread
this.Invoke((MethodInvoker)delegate {
statusScreen.SetProgressPercentage(value); // runs on main thread
});