【发布时间】:2016-11-30 01:01:56
【问题描述】:
我一直在玩多线程并阅读这里的一些问题,但我还没有找到直接解决我所关心的问题的答案。
我有一个在单个线程上运行的应用程序,除了单独窗口中的进度条。根据我的研究,我需要为该表单创建一个新线程,该线程将在其属性更改时重新绘制表单的控件。我已将问题简化为以下简单示例:
这是“主”程序:
class Program
{
static MyForm form;
static void Main(string[] args)
{
form = new MyForm();
form.Show();
doWork();
form.Close();
}
//arbitrary example of processing that takes some period of time
static void doWork()
{
while (form.Value < 100000)
{
form.ChangeVal();
Thread.Sleep(1);
}
return;
}
}
...这是表格。我不包括 VS 自动生成的东西。
public partial class MyForm : Form
{
private int val;
public int Value
{
get { return val; }
set { val = value; }
}
public Thread GUIupdater;
public MyForm()
{
InitializeComponent();
this.Refresh();
}
private void MyForm_Load(object sender, EventArgs e)
{
GUIupdater = new Thread(new ThreadStart(GUIupdaterThread));
GUIupdater.Start();
this.FormClosing += new System.Windows.Forms.FormClosingEventHandler(killThreadOnClose);
}
public void ChangeVal()
{
val++;
}
private void changeLabel(string s)
{
label.Text = s;
label.Refresh();
}
private delegate void labelChanger(string s);
private void GUIupdaterThread()
{
while (true)
{
Invoke(new labelChanger(changeLabel), new object[]{val.ToString()} );
Thread.Sleep(100); //100 ms
}
}
private void killThreadOnClose(object sender, FormClosingEventArgs e)
{
GUIupdater.Abort();
}
}
所以,我的目的是让计算持续运行,窗口的图形更新得相当快。然而,当我运行程序时,invoke 函数只被调用一次,并且标签实际上从未更新!
感谢任何和所有反馈。如果你想在 IDE 中查看代码,可以从Here下载我的项目
编辑:
- 当我添加 Console.WriteLine 语句时,我发现 GUIupdaterThread(用于更新 GUI 的东西)循环总是在 Invoke 语句上“中断”,从未到达“Thread.Sleep”。我将其更改为“BeginInvoke”,这会导致循环正常运行,但这并没有改变 GUI 不更新的事实。
澄清:
关于我的“实际”项目:
- “程序”中的主线程模拟我的软件,这是一个实现接口的插件。我决定在该线程中更改 val / value,而不是在窗口创建的线程中,是经过深思熟虑的。
- 我只能使用 .NET 4.0 。任何更新的功能都帮不了我
【问题讨论】:
-
看来你是在倒退。您的计算应该在线程上运行,而不是更新表单。
-
由于我正在使用的系统,计算必须绝对在主线程上运行,我的目标是在 GUI 窗口中显示结果。必须有某种方法来完成这项工作,对吧?
-
我会摆脱所有那些while循环,只使用一个计时器。我在您的代码中看不到任何需要单独线程的内容。如果这只是一个练习,请遵循 BackgroundWorker 教程。
标签: c# multithreading winforms user-interface