01.using System;
02.using System.Collections.Generic;
03.using System.ComponentModel;
04.using System.Data;
05.using System.Drawing;
06.using System.Text;
07.using System.Windows.Forms;
08.using System.Threading;
09.
10.namespace JPGCompact
11.{
12. public partial class MainForm : Form
13. {
14. // 定义委托
15. private delegate void DelegateWriteResult(string file, bool result);
16.
17. // 与定义的委托签名相同的函数,操作主线程控件
18. private void WriteResult(string fileName, bool result)
19. {
20. if (result)
21. {
22. ListViewItem thisListItem = new ListViewItem();
23. thisListItem.ForeColor = Color.White;
24. thisListItem.BackColor = Color.DarkGreen;
25. thisListItem.SubItems[0].Text = fileName;
26. thisListItem.SubItems.Add("成功");
27. lvResultList.Items.Add(thisListItem);
28. }
29. else
30. {
31. ListViewItem thisListItem = new ListViewItem();
32. thisListItem.ForeColor = Color.White;
33. thisListItem.BackColor = Color.Red;
34. thisListItem.SubItems[0].Text = fileName;
35. thisListItem.SubItems.Add("失败");
36. lvResultList.Items.Add(thisListItem);
37. }
38. }
39.
40. // 启动线程
41. private void btnStart_Click(object sender, EventArgs e)
42. {
43. Thread workThread = new Thread(new ThreadStart(CompressAll));
44. // 设置为背景线程,主线程一旦推出,该线程也不等待而立即结束
45. workThread.IsBackground = true;
46. workThread.Start();
47. }
48.
49. // 线程执行函数
50. private void CompressAll()
51. {
52. // 判断是否需要Invoke,多线程时需要
53. if (this.InvokeRequired)
54. {
55. // 通过委托调用写主线程控件的程序,传递参数放在object数组中
56. this.Invoke(new DelegateWriteResult(WriteResult),
57. new object[] { item, true });
58. }
59. else
60. {
61. // 如果不需要委托调用,则直接调用
62. this.WriteResult(item, true);
63. }
64. }
65. }
66.}
C#跨线程操作控件 问题
因为我的C#程序全是在VS2005上作的,以前学VB.NET的时候机器上是有VS2003的,现在没有2003了,所以我提出的问题不知道VS2003上有没有,看了不少关于线程操作的文章,都没有找到满意的答案. 错误请看代码:
private void change()
{
this.label1.Text = "已发生变化";
}
private void button1_Click(object sender, EventArgs e) //按钮事件
{
Thread cha = new Thread(new ThreadStart(change));
cha.Start();
}
错误提示:未处理 System.InvalidOperationException
Message="线程间操作无效: 从不是创建控件“label1”的线程访问它。" Source="System.Windows.Forms" StackTrace:
在 System.Windows.Forms.Control.get_Handle()
在 System.Windows.Forms.Control.set_WindowText(String value) 在 System.Windows.Forms.Control.set_Text(String value) 在 System.Windows.Forms.Label.set_Text(String value) 在 进程控件.Form1.change() 位置 C:\Documents and
Settings\win.LEGEND-ECDE46B9\My Documents\Visual Studio 2005\Projects\进程控件\进程控件\Form1.cs:行号 15
在 System.Threading.ThreadHelper.ThreadStart_Context(Object state)
在 System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state) 在 System.Threading.ThreadHelper.ThreadStart() 无法跨线程操作,与创建控件的线程不一致
解决方法:
private void change()
{
this.label1.Text = "已发生变化";
}
private void threadchange() //通过委托处理,MSDN上又很详细用法的说明{
MethodInvoker In = new MethodInvoker(change);
this.BeginInvoke(In);
}
private void button1_Click(object sender, EventArgs e)
{
Thread cha = new Thread(new ThreadStart(threadchange));
cha.Start();
}
程序测试成功
例子2:
例子3:
1、取消线程安全保护模式
在程序初始化的时候对要操作的控件设置下面的属性:
System.Windows.Forms.Control.CheckForIllegalCrossThreadCalls = false;
2、副线程函数中通过Control.Invoke(Delegate d)来通过委托方式来调用处理控件的方法。
线程函数:
private void go()
{
while (b)
{
listBox1.Invoke(new DDO(cc));//DDO为委托类型 private delegate void DDO();cc为一个新函数
Thread.Sleep(2000);
}
}
private void cc()//在这个函数中执行操作主线程的控件
{
listBox1.Items.Add(System.DateTime.Now.ToString());
}