在WinForm和WPF中,利用Func,Action,Predicate进行线程UI交互

一、下面这部分主要讲解如何在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


}
}

  • 0
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值