今天看委托的同步与异步调用,看的我蛋好痛首先是:Control的Invoke和BeginInvoke与Delegate的Invoke和BeginInvoke是不同的? 这个我首先就没怎么理解。其实看那个工作线程同步更新UI,看的闷,感觉似懂,非懂。还看到一段话非常有道理,但具体不知道怎么体现到程序里。这段话是这样的“用工作线程去更新界面,在多线程中直接调用界面控件的方法是错误的,正确的做法是将工作线程中涉及到更新界面
的代码封装起来,通过invoke或者begin invoke来调用。(这里在代码里就不懂怎么实现了。)两者的区别就是一个导致工作线程等待,一个则不会。有哪位好心的老大帮忙解释下吧最好弄个例子或者我发个例子using System;
using System.ComponentModel;
using System.Windows.Forms;
namespace WindowsApplication4
{
/**/
/// <summary>
/// gui 类
/// </summary>
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
private void button1_Click(object sender, EventArgs e)
{
//用子线程工作
new System.Threading.Thread(new System.Threading.ThreadStart(StartDownload)).Start();
} //开始下载
public void StartDownload()
{
Downloader downloader = new Downloader();
downloader.onDownLoadProgress += new Downloader.dDownloadProgress(downloader_onDownLoadProgress);
downloader.Start();
}
//同步更新ui
void downloader_onDownLoadProgress(long total, long current)
{
if (this.InvokeRequired)
{
this.Invoke(new Downloader.dDownloadProgress(downloader_onDownLoadProgress), new object[] { total, current });
}
else
{
this.progressBar1.Maximum = (int)total;
this.progressBar1.Value = (int)current;
}
}
} //重点是这段, /**/
/// <summary>
/// 下载类
/// </summary>
public class Downloader
{
//委托
public delegate void dDownloadProgress(long total, long current);
//事件
public event dDownloadProgress onDownLoadProgress;
//开始模拟工作
public void Start()
{
for (int i = 0; i < 100; i++)
{
if (onDownLoadProgress != null)
onDownLoadProgress(100, i);
System.Threading.Thread.Sleep(100);
}
}
}
}我不能再看了,头要爆炸了。明天来看看各位的回复、、、另外我没分了。。不好意思,就30了
的代码封装起来,通过invoke或者begin invoke来调用。(这里在代码里就不懂怎么实现了。)两者的区别就是一个导致工作线程等待,一个则不会。有哪位好心的老大帮忙解释下吧最好弄个例子或者我发个例子using System;
using System.ComponentModel;
using System.Windows.Forms;
namespace WindowsApplication4
{
/**/
/// <summary>
/// gui 类
/// </summary>
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
private void button1_Click(object sender, EventArgs e)
{
//用子线程工作
new System.Threading.Thread(new System.Threading.ThreadStart(StartDownload)).Start();
} //开始下载
public void StartDownload()
{
Downloader downloader = new Downloader();
downloader.onDownLoadProgress += new Downloader.dDownloadProgress(downloader_onDownLoadProgress);
downloader.Start();
}
//同步更新ui
void downloader_onDownLoadProgress(long total, long current)
{
if (this.InvokeRequired)
{
this.Invoke(new Downloader.dDownloadProgress(downloader_onDownLoadProgress), new object[] { total, current });
}
else
{
this.progressBar1.Maximum = (int)total;
this.progressBar1.Value = (int)current;
}
}
} //重点是这段, /**/
/// <summary>
/// 下载类
/// </summary>
public class Downloader
{
//委托
public delegate void dDownloadProgress(long total, long current);
//事件
public event dDownloadProgress onDownLoadProgress;
//开始模拟工作
public void Start()
{
for (int i = 0; i < 100; i++)
{
if (onDownLoadProgress != null)
onDownLoadProgress(100, i);
System.Threading.Thread.Sleep(100);
}
}
}
}我不能再看了,头要爆炸了。明天来看看各位的回复、、、另外我没分了。。不好意思,就30了
{
Thread t = new Thread(new ThreadStart(ThreadMethod));
t.Start();
}
void ThreadMethod()
{
label1.Text = "从非UI线程中修改。。";// 在这里会异常。。
// 线程间操作无效: 从不是创建控件“label1”的线程访问它。。
}正确做法如下: private void button1_Click(object sender, EventArgs e)
{
Thread t = new Thread(new ThreadStart(ThreadMethod));
t.Start();
}
void ThreadMethod()
{
this.Invoke(new MyDelegate(DelegateMethod), "通过委托跨县城访问。。");
}
delegate void MyDelegate(string param);
void DelegateMethod(string param)
{
label1.Text = param;
}
更新所需参数集中到 param 中,如果有多个参数可以用泛型封成一个对象。。
调用Invoke是利用反射在执行
Delegate的BeginInvoke是在新的线程执行的,Control.BeginInvoke是在创建Control的线程里执行的
Control的Invoke和BeginInvoke 一般是在非创建控件的进程中使用,以调用和控件操作有关的方法,你先看看多线程吧
首先定义变量public static Form1 from;
在你调用方法类Downloader里面也设置一个变量Form1 mainform;
且构造函数为:
public override void init(Form1 from)
{
this.mainform = from;
}
启动调用线程的时候给方法类赋值
Downloader.init(form);
下面的泪一定要写在主form里
public void UpdateMessageList(string msg)
{ BeginInvoke(new myDelegate(delegate()
{
/** if (listBoxMsg.Items.Count > 100)
{
listBoxMsg.Items.RemoveAt(0);
}*/
//listBoxMsg.SelectedIndex = listBoxMsg.Items.Add(msg);
textBox1.Text +=msg;
this.textBox1.Focus();//获取焦点
this.textBox1.Select(this.textBox1.TextLength, 0);//光标定位到文本最后
this.textBox1.ScrollToCaret();//滚动到光标处
}));
}在执行线程里调用
this.mainform.UpdateMessageList(string);就能实现,且不会报错
{
Thread t = new Thread(new ThreadStart(ThreadMethod));
t.Start();
}
void ThreadMethod()
{
this.Invoke(new MyDelegate(DelegateMethod), "通过委托跨县城访问。。");
}
delegate void MyDelegate(string param);
void DelegateMethod(string param)
{
label1.Text = param;
}
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 doWorker
{
public partial class Form1 : Form
{
delegate void MyDelegate(int value);
Thread t;
int i = 0;
public Form1()
{
InitializeComponent();
} // 在新的线程中做“需要长时间做的”工作
private void button1_Click(object sender, EventArgs e)
{
t = new Thread(doWork);
t.Start();
} // 要长时间做的工作
void doWork()
{
MyDelegate d = new MyDelegate(setValue);
while (true)
{
++i;
this.Invoke(d, i);
Thread.Sleep(100);
}
} // 更新用户界面
void setValue(int value)
{
label1.Text = value.ToString();
} // 终止线程的执行
private void button2_Click(object sender, EventArgs e)
{
t.Abort();
} }
}
void downloader_onDownLoadProgress(long total, long current)
{
if (this.InvokeRequired)
{
this.Invoke(new Downloader.dDownloadProgress(downloader_onDownLoadProgress), new object[] { total, current });
}
else
{
this.progressBar1.Maximum = (int)total;
this.progressBar1.Value = (int)current;
}
}
}
谁能给我解释下这里? if (this.InvokeRequired) 及其下面的