线程和GUI更新问题 [英] Thread and GUI update problem

查看:63
本文介绍了线程和GUI更新问题的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

对所有人来说,


我有一个GUI程序(使用c#),我已经创建了一个用于加载的线程

一些批量数据,我也是安排这样的GUI程序:


1)加载一个显示等待加载......的表格。等等

2)然后创建一个线程来加载批量数据

3)线程完成后,关闭等待加载。表格

4)显示GUI程序的主要表格


问题是,如果我显示等待表单,那个表单的'GUI将

无法正常工作(没有重绘事件和挂起,即一个空白的

窗口),更糟糕的是线程可能也不能正常工作

(实际上它会停止执行,等待锁定,也许??)


但如果我启动线程而不显示任何形式;它有效吗

完美????!


有什么问题? (同样的事情发生在.Net Compact Framework下)


[主GUI表单的代码片段]

公共类Trial04_02:System.Windows.Forms。表格

{

私有System.Windows.Forms.Label label1;

私有System.Windows.Forms.Button button1;

private System.ComponentModel.Container components = null;

private Trial04_01 mFrmSplash;

private Thread mThr_Main;

private System.Windows .Forms.ListBox listBox1;

private CommonEngine02 mCEng;


public Trial04_02()

{

InitializeComponent();

init();

}


private void InitializeComponent(){}


protected void init()

{

//第一次显示启动表格

this.mFrmSplash = new Trial04_01( );

//this.mFrmSplash.Show();


//第二个创建一个线程加载......

// CommonEngine02是一个包含t的类他

//数据加载函数

this.mCEng = new CommonEngine02(); this.mThr_Main = new Thread

(new ThreadStart(this.mCEng.threadTask));

this.mThr_Main.Start();

this.mThr_Main.Join();

this.mFrmSplash.Close();


//第3个其他设置

//取回加载的数据

System.Collections.ArrayList oArr

= this.mCEng.getArr_Data();

for( int i = 0; i< oArr.Count; i ++)

{

this.listBox1.Items.Add(oArr [i]);

}

this.Show();

}


static void Main()

{

Application.Run(新Trial04_02());

}

}

}


[/ code]

来自Jason(Kusanagihk)

To all,

I have a GUI program (use c#), and I have create a Thread for loading
some bulk data, I also arrange the GUI program like this:

1) load a form showing "Wait for loading..." etc
2) a Thread is then created to load the bulk data
3) after the thread has completed, close the "Wait for loading" form
4) show the main form for the GUI program

The problem is that if I show the "waiting" form, that form''s GUI will
not work properly (no repaint event and hangs around, ie. a blank
window), the worse thing is that the Thread may not work properly too
(actually it will stop executing, waiting for locks, maybe ??)

But if I start the Thread without showing any forms; it works
perfectly ????!

What''s wrong ?? (the same things happen under .Net Compact Framework)

[code snippet for the main GUI form]
public class Trial04_02 : System.Windows.Forms.Form
{
private System.Windows.Forms.Label label1;
private System.Windows.Forms.Button button1;
private System.ComponentModel.Container components = null;
private Trial04_01 mFrmSplash;
private Thread mThr_Main;
private System.Windows.Forms.ListBox listBox1;
private CommonEngine02 mCEng;

public Trial04_02()
{
InitializeComponent();
init ();
}

private void InitializeComponent() {}

protected void init ()
{
// 1st show splash form
this.mFrmSplash = new Trial04_01 ();
//this.mFrmSplash.Show ();

// 2nd create a thread to load sth...
// CommonEngine02 is a class containing the
// data loading function
this.mCEng = new CommonEngine02 (); this.mThr_Main = new Thread
(new ThreadStart (this.mCEng.threadTask));
this.mThr_Main.Start ();
this.mThr_Main.Join ();
this.mFrmSplash.Close ();

// 3rd other setup(s)
// get back the loaded data
System.Collections.ArrayList oArr
= this.mCEng.getArr_Data ();
for (int i=0; i<oArr.Count; i++)
{
this.listBox1.Items.Add (oArr[i]);
}
this.Show ();
}

static void Main ()
{
Application.Run (new Trial04_02 ());
}
}
}

[/code]
From Jason (Kusanagihk)

推荐答案

嗨Jason,


看起来你的表格是mFrmSplash。 (主线程)等待

" this.mThr_Main.Join()"但是它不能被无效。


我可以提议:

A)" mFrmSplash.Close()&& this.Show()"在

thread" mThr_Main" ;.



B)运行将等待的第三个线程(this.mThr_Main.Join() ")

然后将关闭启动窗体并显示主窗口。


Regads


Marcin
Hi Jason,

It looks like your form "mFrmSplash" (main thread) waits at
"this.mThr_Main.Join()" line, so it can not be "invalidated".

I can propose:
A) "mFrmSplash.Close() && this.Show()" within
thread "mThr_Main".
or
B) run third thread that will wait ("this.mThr_Main.Join()")
and then will close the splash form and show the main window.

Regads

Marcin
对所有人来说,

我有一个GUI程序(使用c#),我已经创建了一个用于加载一些批量数据的线程,我还安排这样的GUI程序:

1)加载一个显示等待加载...的表单。等等2)然后创建一个线程来加载批量数据
3)线程完成后,关闭等待加载。表格
4)显示GUI程序的主要形式

问题是,如果我显示等待表单,那个表单的'GUI将无法正常工作(没有重绘事件和挂起,即一个空白的窗口),更糟糕的是Thread也可能无法正常工作
(实际上它会停止执行,等待锁定,也许??)

但是如果我在没有显示任何形式的情况下启动线程;它的工作原理完美????!

有什么问题? (同样的事情发生在.Net Compact Framework下)

[主GUI表单的代码片段]
公共类Trial04_02:System.Windows.Forms.Form
{
private System.Windows.Forms.Label label1;
private System.Windows.Forms.Button button1;
private System.ComponentModel.Container components = null;
private Trial04_01 mFrmSplash; 私有System.Windows.Forms.ListBox listBox1;
私有CommonEngine02 mCEng;

public Trial04_02()
{/> InitializeComponent ();
init();
}
private void InitializeComponent(){}

protected void init()
{
// 1st show splash form
this.mFrmSplash = new Trial04_01();
//this.mFrmSplash.Show();

//第二次创建一个帖子加载......
// CommonEngine02是一个包含
//数据加载的类功能
this.mCEng = new CommonEngine02(); this.mThr_Main = new Thread
(新的ThreadStart(this.mCEng.threadTask));
this.mThr_Main.Start();
this.mThr_Main.Join();
this.mFrmSplash.Close();

//第三个其他设置
//取回加载的数据
System.Collections.ArrayList oArr
= this.mCEng.getArr_Data();
for(int i = 0; i< oArr.Count; i ++)
{
this.listBox1.Items.Add(oArr [i]);
}
this.Show();
}
静态无效Main()
{/> Application.Run(new Trial04_02() );
}
}

[/ code]

来自Jason(Kusanagihk)
To all,

I have a GUI program (use c#), and I have create a Thread for loading
some bulk data, I also arrange the GUI program like this:

1) load a form showing "Wait for loading..." etc
2) a Thread is then created to load the bulk data
3) after the thread has completed, close the "Wait for loading" form
4) show the main form for the GUI program

The problem is that if I show the "waiting" form, that form''s GUI will
not work properly (no repaint event and hangs around, ie. a blank
window), the worse thing is that the Thread may not work properly too
(actually it will stop executing, waiting for locks, maybe ??)

But if I start the Thread without showing any forms; it works
perfectly ????!

What''s wrong ?? (the same things happen under .Net Compact Framework)

[code snippet for the main GUI form]
public class Trial04_02 : System.Windows.Forms.Form
{
private System.Windows.Forms.Label label1;
private System.Windows.Forms.Button button1;
private System.ComponentModel.Container components = null;
private Trial04_01 mFrmSplash;
private Thread mThr_Main;
private System.Windows.Forms.ListBox listBox1;
private CommonEngine02 mCEng;

public Trial04_02()
{
InitializeComponent();
init ();
}

private void InitializeComponent() {}

protected void init ()
{
// 1st show splash form
this.mFrmSplash = new Trial04_01 ();
//this.mFrmSplash.Show ();

// 2nd create a thread to load sth...
// CommonEngine02 is a class containing the
// data loading function
this.mCEng = new CommonEngine02 (); this.mThr_Main = new Thread
(new ThreadStart (this.mCEng.threadTask));
this.mThr_Main.Start ();
this.mThr_Main.Join ();
this.mFrmSplash.Close ();

// 3rd other setup(s)
// get back the loaded data
System.Collections.ArrayList oArr
= this.mCEng.getArr_Data ();
for (int i=0; i<oArr.Count; i++)
{
this.listBox1.Items.Add (oArr[i]);
}
this.Show ();
}

static void Main ()
{
Application.Run (new Trial04_02 ());
}
}
}

[/code]
From Jason (Kusanagihk)



Jason Jacob< 50 ****** @ alumni.cityu.edu.hk>写道:
Jason Jacob <50******@alumni.cityu.edu.hk> wrote:
我有一个GUI程序(使用c#),我已经创建了一个用于加载一些批量数据的线程,我还安排了这样的GUI程序:
< 1)加载显示等待加载......的表格。等等2)然后创建一个线程来加载批量数据
3)线程完成后,关闭等待加载。表格
4)显示GUI程序的主要表单
I have a GUI program (use c#), and I have create a Thread for loading
some bulk data, I also arrange the GUI program like this:

1) load a form showing "Wait for loading..." etc
2) a Thread is then created to load the bulk data
3) after the thread has completed, close the "Wait for loading" form
4) show the main form for the GUI program




如果你马上就去创建一个新线程没有意义br />
来调用Join就可以了。相反,你需要正常运行UI线程,

并在加载完成时进行某种调用以告诉加载

屏幕关闭。


请参阅 http:// www。 pobox.com/~skeet/csharp/multithreading.html 了解更多

信息。


-

Jon Skeet - < sk *** @ pobox.com>
http:/ /www.pobox.com/~skeet

如果回复该群组,请不要给我发邮件



There''s no point in creating a new thread if you''re immediately going
to call Join on it. Instead, you need to run the UI thread as normal,
and have some kind of call when the load finishes to tell the loading
screen to close.

See http://www.pobox.com/~skeet/csharp/multithreading.html for more
information.

--
Jon Skeet - <sk***@pobox.com>
http://www.pobox.com/~skeet
If replying to the group, please do not mail me too


致Jon ,


我已经改变了你所说的代码,实际上没有变化

问题:


public Form1()

{

InitializeComponent();


oFrm2 = new Form2();

线程t1 =新线程

(新的ThreadStart(oFrm2.threadTask));

t1.Start();


loaderTask();

oFrm2.mBool_Stop = true;

lock(this)

{

t1.Join();

oFrm2.Close();

}

}


上面的代码是操作的构造函数代码,threadTask

将改变Splash Form''Label'的文本,但是当它们获得它们时

已执行,Splash Form的UI未正确更新...


但是,我试图使用oFrm2.ShowDialog()而不是oFrm2。显示

(),结果就是Splash Form可以正常显示,但是

实际上它不是一个Thread,因为表单正在等待你

关闭它(Dialog),然后它将继续开始其他任务

之前......


来自Jason(Kusanagihk)
To Jon,

I''ve changed the code as you''ve said, actually there is no change in
the problem:

public Form1()
{
InitializeComponent();

oFrm2 = new Form2 ();
Thread t1 = new Thread
(new ThreadStart (oFrm2.threadTask));
t1.Start ();

loaderTask ();
oFrm2.mBool_Stop = true;
lock (this)
{
t1.Join ();
oFrm2.Close ();
}
}

The above code is the constructor code for the operation, threadTask
will change the Splash Form''s Label''s Text, but when got them
executed, the Splash Form''s UI is not updating properly...

But then, I''ve tried to use oFrm2.ShowDialog () instead of oFrm2.Show
(), the result is that the Splash Form can be shown properly, but
actually it is not a Thread, since the form is waiting for you to
close it (Dialog), then it will continue the other tasks started
earlier...

From Jason (Kusanagihk)


这篇关于线程和GUI更新问题的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆