c#委托
{mtitle}winform{/mtitle}
delegate void SetTextCallback(double[] text);
SetTextCallback deg = new SetTextCallback(SetText);
this.Invoke(deg, new object[] { new double[] { Convert.ToDouble(cnt), val,max,min, change } });
private void SetText(double[] text)
{
label19.Text = text[0] + "";
textBox6.Text = text[3] + "";
textBox7.Text = text[2] + "";
textBox3.Text = (1000/text[4]).ToString("f2");
label26.Text = (text[2] - text[3]).ToString("f3");
}
{mtitle}wpf{/mtitle}
App.Current.Dispatcher.BeginInvoke(new Action(() => {
Fpsnum.Content = fpsnum + "";
}));
{mtitle}高级用法{/mtitle}
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using System.Windows.Forms;
namespace multiThread
{
public partial class FormMain : Form
{
public FormMain()
{
InitializeComponent();
//指定不再捕获对错误线程的调用
Control.CheckForIllegalCrossThreadCalls = false;
}
#region 最基本的多线程调用
private void btn_Update_Click(object sender, EventArgs e)
{
Thread t = new Thread(new ThreadStart(DataUpdate));
t.Start();
}
/// <summary>
/// 数据处理
/// </summary>
private void DataUpdate()
{
//通过循环,模拟数据处理过程
for (int i = 0; i < 10; i++)
{
//在未设置CheckForIllegalCrossThreadCalls情况下,如果直接操作memoEdit_main,则会弹出【线程间操作无效: 从不是创建控件XXX的线程访问它】错误
memoEdit_main.Text = memoEdit_main.Text + "\r\n" + DateTime.Now.ToString();
//MessageBox.Show(DateTime.Now.ToString());
//暂停1s
Thread.Sleep(1000);
}
MessageBox.Show("处理完成!");
}
#endregion
#region 使用INVOKE方法通过子线程更新主线程控件
/// <summary>
/// 1、定义界面更新操作
/// 更新Memoedit信息并定位到行尾
/// </summary>
/// <param name="strMsg"></param>
private void MainThreadUIOper(string strMsg)
{
memoEdit_main.Text = memoEdit_main.Text + "\r\n" + strMsg;
memoEdit_main.SelectionStart = memoEdit_main.Text.Length;
memoEdit_main.ScrollToCaret();
Application.DoEvents();
}
/// <summary>
/// 2、定义委托事件,用于委托上一步定义的MainThreadUIOper
/// </summary>
/// <param name="str"></param>
public delegate void UIOperDelegate(string str);
/// <summary>
/// 3、定义子线程执行操作函数
/// </summary>
/// <param name="strMsg"></param>
private void DoWork(object para)
{
string strPara = para.ToString();
for (int i = 0; i < 10; i++)
{
//注意BeginInvoke和Invoke的区别,根据实际情况选用,前者为异步,后者为同步
//也可以将new UIOperDelegate(MainThreadUIOper)提出来单独定义 UIOperDelegate temp = new UIOperDelegate(MainThreadUIOper); 后面公共引用
this.Invoke(new UIOperDelegate(MainThreadUIOper), new object[] { DateTime.Now.ToString() });
//暂停1s
Thread.Sleep(1000);
}
//完成后发送相关信息
this.BeginInvoke(new UIOperDelegate(MainThreadUIOper), new Object[] { "测试完成!" });
//使用 MessageBoxOptions.ServiceNotification是的窗口始终在最上一层显示
MessageBox.Show("提示", "测试完成!", MessageBoxButtons.OK, MessageBoxIcon.None, MessageBoxDefaultButton.Button1, MessageBoxOptions.ServiceNotification);
}
/// <summary>
/// 4、在主线程中开启子线程并传递参数给子线程
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void btn_start_Click(object sender, EventArgs e)
{
memoEdit_main.Text = "";
memoEdit_main.Update();
//注意,如果需要给子线程传递参数,需要使用ParameterizedThreadStart,否则使用ThreadStart即可,后面直接thread.Start();
Thread thread = new Thread(new ParameterizedThreadStart(DoWork));
thread.Start("para");
}
#endregion
#region 使用BackgroundWorker方法进行异步操作
/// <summary>
/// 1、定义BackgroundWorker对象
/// </summary>
private BackgroundWorker m_backgroundWorker = null;
/// <summary>
/// 2、主体方法,定义子操作函数
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
public void m_backgroundWorker_DoWork(object sender, DoWorkEventArgs e)
{
for (int i = 0; i < 10; i++)
{
//在线程中更新UI(通过ReportProgress方法)
m_backgroundWorker.ReportProgress(50, DateTime.Now.ToString());
//暂停1s
Thread.Sleep(1000);
}
//完成后发送相关信息
m_backgroundWorker.ReportProgress(100, "操作完成");
}
/// <summary>
/// 3、定义执行UI更新事件
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
public void m_backgroundWorker_ProgressChanged(object sender, ProgressChangedEventArgs e)
{
memoEdit_main.Text = memoEdit_main.Text + "\r\n" + e.UserState.ToString();
memoEdit_main.SelectionStart = memoEdit_main.Text.Length;
memoEdit_main.ScrollToCaret();
Application.DoEvents();
}
/// <summary>
/// 4、注册事件(执行线程主体、执行UI更新事件)
/// 启动子线程
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void btn_prop_Click(object sender, EventArgs e)
{
m_backgroundWorker = new System.ComponentModel.BackgroundWorker();
//设置报告进度更新,注意此选项必须设置为true,否则无法返回进度
m_backgroundWorker.WorkerReportsProgress = true;
//注册线程主体方法
m_backgroundWorker.DoWork += new DoWorkEventHandler(m_backgroundWorker_DoWork);
//注册更新UI方法
m_backgroundWorker.ProgressChanged += new ProgressChangedEventHandler(m_backgroundWorker_ProgressChanged);
//注册子线程执行完成事件
m_backgroundWorker.RunWorkerCompleted += new System.ComponentModel.RunWorkerCompletedEventHandler(this.m_backgroundWorker_RunWorkerCompleted);
this.m_backgroundWorker.RunWorkerAsync();
}
/// <summary>
/// 子线程执行完成后操作
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
public void m_backgroundWorker_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
{
MessageBox.Show("操作完成!");
}
#endregion
#region 通过UI线程的SynchronizationContext的Post/Send方法更新UI
/// <summary>
/// 1、定义UI线程的同步上下文
/// </summary>
SynchronizationContext m_SyncContext = null;
/// <summary>
/// 3、定义线程的主体方法
/// </summary>
private void ThreadProcSafePost()
{
for (int i = 0; i < 10; i++)
{
//在线程中更新UI(通过UI线程同步上下文m_SyncContext)
m_SyncContext.Post(SetTextSafePost, DateTime.Now.ToString());
//暂停1s
Thread.Sleep(1000);
}
//完成后发送相关信息
m_SyncContext.Post(SetTextSafePost, "操作完成");
}
/// <summary>
/// 4、更新UI方法
/// </summary>
/// <param name="text"></param>
private void SetTextSafePost(object str)
{
memoEdit_main.Text = memoEdit_main.Text + "\r\n" + str.ToString();
memoEdit_main.SelectionStart = memoEdit_main.Text.Length;
memoEdit_main.ScrollToCaret();
Application.DoEvents();
}
/// <summary>
/// 2、获取UI线程同步上下文(建议在窗体构造函数或FormLoad事件中,这里因为测试方便,直接放在了这里)
/// 启动线程
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void btn_sync_Click(object sender, EventArgs e)
{
//获取UI线程同步上下文
m_SyncContext = SynchronizationContext.Current;
Thread thread = new Thread(new ThreadStart(this.ThreadProcSafePost));
thread.Start();
}
#endregion
}
}
评论 (0)