2013-07-10
卡住很有可能是因为在窗体的Invoke里进行了大量运算。
一般情况,在线程中就仅仅进行和窗体无关的计算,必要时,使用Invoke进行一些窗体状态的更新,这样完全不会导致卡住冻结。
2010-09-25 18:57更新:根据各位朋友的回复,做了一些更新。
加入了BackgroundWorker和MethodInvoker
有时候我们在窗体的执行方法中,会延迟很久,那样就会造成操作窗体(界面)卡住(冻结)的情况出现,这样的用户体验非常糟糕。
在使用线程操作,则可能会避免这种情况。
因此我做了一个测试。
在这方面的设计,我也是初学者,因此,有不对的地方,请前辈指点迷津。
///
<summary>
///
执行的主逻辑
///
</summary>
///
<param name="obj"></param>
private
void
RunMethod(
object
obj)
{
ThreadTest tt
=
new
ThreadTest();
int
curValue
=
0
;
for
(
int
i
=
0
; i
<
20
; i
++
)
{
curValue
=
tt.GetRandomNum();
//
不添加5的项,主要为了添加业务复杂性
while
(curValue
==
5
)
{
Thread.Sleep(
2000
);
//
制造延迟,测试是否会冻结(卡)主窗口
curValue
=
tt.GetRandomNum();
}
Thread.Sleep(
2000
);
//
制造延迟,测试是否会冻结(卡)主窗口
if
(
this
.InvokeRequired)
{
this
.Invoke(
new
MethodInvoker(
delegate
()
{
this
.lsbShow.Items.Add(curValue);
this
.lsbShow.SelectedIndex
=
lsbShow.Items.Count
-
1
;
}));
}
else
{
lsbShow.Items.Add(curValue);
}
}
this
.Invoke(
new
MethodInvoker(
delegate
()
{
this
.btnRun.Enabled
=
true
;
this
.btnThread.Enabled
=
true
;
btnBackgroundWorker.Enabled
=
true
;
this
.lsbShow.Items.Add(
"
Done
"
);
this
.lsbShow.SelectedIndex
=
lsbShow.Items.Count
-
1
;
}));
}
用到的测试类
public
delegate
void
CommonDelegate();
public
class
ThreadTest
{
public
ThreadTest() { }
public
int
GetRandomNum()
{
Random rd
=
new
Random();
return
rd.Next(
1
,
10
);
}
}
调用按钮事件
private
void
btnRun_Click(
object
sender, EventArgs e)
{
RunStart();
ThreadPool.QueueUserWorkItem(
new
WaitCallback(RunMethod));
}
private
void
btnThread_Click(
object
sender, EventArgs e)
{
RunStart();
Thread td
=
new
Thread(
new
ParameterizedThreadStart(RunMethod));
td.Start(
""
);
}
private
void
RunStart()
{
lsbShow.Items.Clear();
btnRun.Enabled
=
false
;
btnThread.Enabled
=
false
;
btnBackgroundWorker.Enabled
=
false
;
}
private
void
btnBackgroundWorker_Click(
object
sender, EventArgs e)
{
RunStart();
using
(BackgroundWorker bw
=
new
BackgroundWorker())
{
bw.DoWork
+=
new
DoWorkEventHandler(bw_DoWork);
bw.RunWorkerAsync();
}
}
void
bw_DoWork(
object
sender, DoWorkEventArgs e)
{
RunMethod(
""
);
}
测试源码http://files.cnblogs.com/yelaiju/WinFormSynTest.rar