在WinForm和WPF中,利用Func,Action,Predicate进行线程UI交互
程序员文章站
2022-06-10 18:07:06
...
一、下面这部分主要讲解如何在WinForm中利用这些委托进行线程和界面的交互。
1、首先对于Func来说,由于其必须具有返回值,所以我们可以利用如下代码来实现线程和界面的交互:
#region 利用Func实现线程和界面交互
private void AlternationUsingFunc(object text)
{
//无参数,但是返回值为bool类型
this.Invoke(new Func<bool>(delegate()
{
button1.Text = text.ToString();
return true; //返回值
}));
}
private void AlternationUsingFuncThread()
{
WaitCallback waitCallBack = new WaitCallback(this.AlternationUsingFunc);
ThreadPool.QueueUserWorkItem(waitCallBack, "Func的使用");
}
private void button1_Click(object sender, EventArgs e)
{
AlternationUsingFuncThread();
}
#endregion
其中
this.Invoke(new Func<bool>(delegate()
{
button1.Text = text.ToString();
return true; //返回值
}));
这段代码中利用了Func<TResult>这种类型,也就是没有传入参数,但是有一个bool类型的返回值,然后将这个函数利用加入到线程池中,最后运行,这里我们成功的设置了button1的text为“Func的使用”。
2、然后,对于Action来说,由于其可以无参,无返回值,那么它的交互方式最为简便,同时也是使用最多的,先看有参的调用方式:
#region 利用Action实现线程和界面交互
private void AlternationUsingAction(object text)
{
//需要一个T类型的参数,无返回值
this.Invoke(new Action<object>(delegate(object myText)
{
myText = text;
button2.Text = text.ToString();
}),text);
}
private void AlternationUsingActionThread()
{
WaitCallback waitCallBack = new WaitCallback(this.AlternationUsingAction);
ThreadPool.QueueUserWorkItem(waitCallBack,"Action的使用");
}
private void button2_Click(object sender, EventArgs e)
{
AlternationUsingActionThread();
}
#endregion
在上面的代码示例中,我们使用了带有一个传入参数的Action委托,当然了,匿名类型delegate(object myText)匿名代理了具有一个传入参数的函数。
其实简单点来说,可以像如下方式使用:
this.Invoke((Action)(()=>
{
button2.Text = text.ToString();
}));
这样就显得非常的方便。
3、最后一个当然是Predicate委托,和上面类似,只是写起来麻烦一些,它需要一个传入参数,并且返回一个bool类型:
#region 利用Predicate实现线程和界面的交互
private void AlternationUsingPrecidate(object text)
{
//需要一个T类型的参数,返回bool类型
this.Invoke(new Predicate<object>(delegate(object myText)
{
myText = text;
button3.Text = myText.ToString();
return true; //返回值
}),text);
}
private void AlternationUsingPrecidateThread()
{
WaitCallback waitCallBack = new WaitCallback(this.AlternationUsingPrecidate);
ThreadPool.QueueUserWorkItem(waitCallBack,"Predicate的使用");
}
private void button3_Click(object sender, EventArgs e)
{
AlternationUsingPrecidateThread();
}
#endregion
具体的注释我已经写在代码中了,最后运行,能成功的将button3的Text置为“Predicate的使用.”
4、下面是全部实现代码:
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.Threading;
namespace DelegateIntegrateWinFormApp
{
public partial class mainFrm : Form
{
public mainFrm()
{
InitializeComponent();
}
private void mainFrm_Load(object sender, EventArgs e)
{
/****************************注意例子中的使用方法****************
* delegate TResult Func<TResult>(); 无参,但是返回值为TResult类型
* delegate void Action<T>(T1 arg1); 有一个参数arg1,但是无返回值
* delegate bool Predicate<T>(T arg); 有一个参数arg,返回bool类型
* **************************************************************/
}
#region 利用Func实现线程和界面交互
private void AlternationUsingFunc(object text)
{
//无参数,但是返回值为bool类型
this.Invoke(new Func<bool>(delegate()
{
button1.Text = text.ToString();
return true; //返回值
}));
}
private void AlternationUsingFuncThread()
{
WaitCallback waitCallBack = new WaitCallback(this.AlternationUsingFunc);
ThreadPool.QueueUserWorkItem(waitCallBack, "Func的使用");
}
private void button1_Click(object sender, EventArgs e)
{
AlternationUsingFuncThread();
}
#endregion
#region 利用Action实现线程和界面交互
private void AlternationUsingAction(object text)
{
//需要一个T类型的参数,无返回值
this.Invoke(new Action<object>(delegate(object myText)
{
myText = text;
button2.Text = text.ToString();
}),text);
}
private void AlternationUsingActionThread()
{
WaitCallback waitCallBack = new WaitCallback(this.AlternationUsingAction);
ThreadPool.QueueUserWorkItem(waitCallBack,"Action的使用");
}
private void button2_Click(object sender, EventArgs e)
{
AlternationUsingActionThread();
}
#endregion
#region 利用Predicate实现线程和界面的交互
private void AlternationUsingPrecidate(object text)
{
//需要一个T类型的参数,返回bool类型
this.Invoke(new Predicate<object>(delegate(object myText)
{
myText = text;
button3.Text = myText.ToString();
return true; //返回值
}),text);
}
private void AlternationUsingPrecidateThread()
{
WaitCallback waitCallBack = new WaitCallback(this.AlternationUsingPrecidate);
ThreadPool.QueueUserWorkItem(waitCallBack,"Predicate的使用");
}
private void button3_Click(object sender, EventArgs e)
{
AlternationUsingPrecidateThread();
}
#endregion
}
}
二、那么,现在对于WPF来说,该如何来使用呢?其实在WPF中,和winform中类似,只是在WPF中要实现线程和界面的交互,我们需要用Dispatcher来实现,也就是形如Control.Dispatcher.Invoke()的方式,由于与Winform实现方式无多大差别,这里我就直接附上全部代码:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
using System.Threading;
namespace WpfApplication1
{
/// <summary>
/// Interaction logic for Window1.xaml
/// </summary>
public partial class Window1 : Window
{
public Window1()
{
InitializeComponent();
}
private void Window_Loaded(object sender, RoutedEventArgs e)
{
/****************************注意例子中的使用方法****************
* delegate TResult Func<TResult>(); 无参,但是返回值为TResult类型
* delegate void Action(); 无参,无返回值
* delegate bool Predicate<T>(T arg); 有一个参数arg,返回bool类型
* 需要注意,与WinForm中不同的是,WPF中需要利用Control.Dispatcher.Invoke来实现,其他类似.
* **************************************************************/
}
#region 利用Func实现线程和界面交互
private void AlternationUsingFunc(object text)
{
//无参数,但是返回值为bool类型
button1.Dispatcher.Invoke(new Func<bool>(delegate()
{
button1.Content = text.ToString();
return true; //返回值
}));
}
private void AlternationUsingFuncThread()
{
WaitCallback waitCallBack = new WaitCallback(this.AlternationUsingFunc);
ThreadPool.QueueUserWorkItem(waitCallBack, "Func的使用");
}
private void button1_Click(object sender, RoutedEventArgs e)
{
AlternationUsingFuncThread();
}
#endregion
#region 利用Action实现线程和界面交互
private void AlternationUsingAction(object text)
{
//无参数,无返回值
//button2.Dispatcher.Invoke(new Action(delegate()
//{
// button2.Content = text.ToString();
//}));
//或者
button2.Dispatcher.Invoke((Action)(()=>
{
button2.Content = text.ToString();
}));
}
private void AlternationUsingActionThread()
{
WaitCallback waitCallBack = new WaitCallback(this.AlternationUsingAction);
ThreadPool.QueueUserWorkItem(waitCallBack, "Action的使用");
}
private void button2_Click(object sender, RoutedEventArgs e)
{
AlternationUsingActionThread();
}
#endregion
#region 利用Predicate实现线程和界面的交互
private void AlternationUsingPrecidate(object text)
{
//需要一个T类型的参数,返回bool类型
this.button3.Dispatcher.Invoke(new Predicate<object>(delegate(object myText)
{
myText = text;
button3.Content = myText.ToString();
return true; //返回值
}), text);
}
private void AlternationUsingPrecidateThread()
{
WaitCallback waitCallBack = new WaitCallback(this.AlternationUsingPrecidate);
ThreadPool.QueueUserWorkItem(waitCallBack, "Predicate的使用");
}
private void button3_Click(object sender, RoutedEventArgs e)
{
AlternationUsingPrecidateThread();
}
#endregion
}
}