欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

在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


}
}

相关标签: c#和dot net