WPF 线程与UI进行联动 界面进行假死问题
本人算是一个WPF 小白,我是从winform转到WPF,线程这个东西么,只要有程序有数据,就要用到。这可让人头疼死了,我明明在Winform 的线程玩的很,不知道为啥,在WPF却不是那么好用!!!
经过几个小时的奋斗和查询,我终于搞通了。先给看一下我借助的文档:
(https://www.cnblogs.com/jeffy-chang/p/7123792.html)
这个文档说的很明白,不要因为全是字就是不看了,一定要仔细看,你就发现奥妙了。
好的给大家看我的代码:
//定义一个线程
Thread thread;
//这个是为了阻塞线程用的,因为我需要他可以暂停,暂停之后还能继续运行
static public AutoResetEvent TaskEvent = new AutoResetEvent(false);
private bool bWhileFlag = true;
这个部分是主函数:
public MainWindow()
{
InitializeComponent();
//运行线程
thread = new Thread( new ThreadStart(ModifuUi));
thread.Start();
}
这个是鼠标离开 继续线程运行
///
/// 鼠标离开
///
///
///
private void ButtonList_MouseLeave(object sender, MouseEventArgs e)
{
bWhileFlag = true;
TaskEvent.Set();
}
这部分是鼠标进入边缘,线程停止运行
///
/// 鼠标进入
///
///
///
private void ButtonList_MouseEnter(object sender, MouseEventArgs e)
{
storyboard5.Pause();
bWhileFlag = false;
}
重点来了,我的线程部分---------- 颜色自己取 我就不删除了
public void ModifuUi()
{
#region 颜色
colors.Add("#FF8C69");
colors.Add("#FF8247");
colors.Add("#FF7256");
colors.Add("#FF6347");
colors.Add("#FFA07A");
colors.Add("#FF82AB");
colors.Add("#FF7F00");
colors.Add("#FF69B4");
colors.Add("#FFA500");
colors.Add("#FF83FA");
colors.Add("#FF7F24");
colors.Add("#FF6A6A");
colors.Add("#FFA54F");
colors.Add("#FF8C00");
colors.Add("#FF7F50");
colors.Add("#FF6EB4");
colors.Add("#00CED1");
colors.Add("#00C5CD");
colors.Add("#008B8B");
colors.Add("#00688B");
colors.Add("#00E5EE");
colors.Add("#00CD00");
colors.Add("#009ACD");
colors.Add("#00868B");
colors.Add("#00EE00");
colors.Add("#00CD66");
colors.Add("#00B2EE");
colors.Add("#008B00");
colors.Add("#00EE76");
colors.Add("#00CDCD");
colors.Add("#00BFFF");
colors.Add("#008B45");
colors.Add("#87CEFF");
colors.Add("#858585");
colors.Add("#838B83");
colors.Add("#7FFF00");
colors.Add("#7D7D7D");
colors.Add("#87CEFA");
colors.Add("#848484");
colors.Add("#836FFF");
colors.Add("#7F7F7F");
colors.Add("#7D26CD");
colors.Add("#87CEEB");
colors.Add("#8470FF");
colors.Add("#828282");
colors.Add("#7EC0EE");
colors.Add("#7CFC00");
colors.Add("#878787");
colors.Add("#838B8B");
colors.Add("#7FFFD4");
colors.Add("#7D9EC0");
colors.Add("#7CCD7C");
#endregion
Button[] buttons = { bt1, bt2, bt3, bt4, bt5 };
int i = 0;
while (true)
{
this.ButtonList1.Dispatcher.Invoke(new Action(delegate {
//设置焦点
//buttons[i].Focus();
//设置背景色
buttons[i].Background = new SolidColorBrush((Color)ColorConverter.ConvertFromString(colors[new Random().Next(0, 51)]));
switch (buttons[i].Name)
{
case "bt1":
TB1.Text = "人工清扫作业";
TB2.Text = "43";
break;
case "bt2":
TB1.Text = "路面洒水作业";
TB2.Text = "13";
break;
case "bt3":
TB1.Text = "机扫作业";
TB2.Text = "20";
break;
case "bt4":
TB1.Text = "餐饮回收";
TB2.Text = "10";
break;
case "bt5":
TB1.Text = "巡回保洁作业";
TB2.Text = "60";
break;
}
}));
//注意 只要不是控件的部分 全都要拿出更新UI委托外面来,尤其是延时函数 很容易造成界面假死
Thread.Sleep(1000);
if (!bWhileFlag)
{
TaskEvent.WaitOne();
}
i++;
if (i == 5)
{
i = 0;
}
}
}
我感觉应该会有人问,我在更新Button 的时候用For函数 不就行了,但是我用了 ,因为我想的是Button 控件刷新背景色慢一点,可是呢,那不行啊,我把for到ui委托里,就要把延时函数加进去,这个时候,界面就会假死!!!所以我更改了办法。
注: 如果你们不需要线程暂停、开始等操作,我建议可以使用Task 线程函数 这个是真的简单,我刚开始也想要用Task 但是问题是,我找了好多资料,都是刚开始运行好好的,但是我需要暂停运行的时候,就出现问题了!可以暂停,界面假死!!!很难受。如果大家有更好的请高速我!!!
我把我的Task 线程使用粘贴出来:
task1 = new Task(() =>
{
//跨线程处理 控件和线程不在一个线程内 就要使用跨线程处理
App.Current.Dispatcher.Invoke(async () =>
{
While(true)
{
for(int i=0 ;i<5 ;i++)
{
//设置焦点
//buttons[i].Focus();
//设置背景色
buttons[i].Background = new SolidColorBrush((Color)ColorConverter.ConvertFromString(colors[new Random().Next(0, 51)]));
switch (buttons[i].Name)
{
case "bt1":
TB1.Text = "人工清扫作业";
TB2.Text = "43";
break;
case "bt2":
TB1.Text = "路面洒水作业";
TB2.Text = "13";
break;
case "bt3":
TB1.Text = "机扫作业";
TB2.Text = "20";
break;
case "bt4":
TB1.Text = "餐饮回收";
TB2.Text = "10";
break;
case "bt5":
TB1.Text = "巡回保洁作业";
TB2.Text = "60";
break;
}
}
}
}));
}
task1.start();
这段代码,纯手打的,可能会出现错误 ,也不可能出现!
bt1-5是我的Button控件 ,TB1-2是我的TextBlox控件!