C#中的invoke()如何控制线程啊
作者&投稿:宏叙 (若有异议请与网页底部的电邮联系)
直接放进去有什么意义啊
在UI线程里干UI线程本来应该的活和不应该干的活,那你还用啥子多线程啊
准备
public delegate void CallBackDeletegate();
public void MyCalBack() { doSomthing.. }
CallBackDeletegate del=MyCalBack;
线程
public void Mythread(object obj)
{
....
CallBackDeletegate Call=obj as CallBackDeletegate
Call.Invoke() 或者 Call.BeginInvoke()
}
Thread th=new Thread(Mythread);
th.start(del);
另外一种写法
public void MyCalBack(IAsyncResult ar) { doSomthing.. }
public delegate void MainDeletegate();
public void Mythread() {doSomthing..}
MainDeletegate mainDel=Mythread;
mainDel.beginInvoke( new AsyncCallback(MyCalBack),null);
不知道下面这个你是否用的上。
private void W_Reveive(string text)//这里调用了一个委托,这样就可以在主线程刷新数据了
{
if (this.textBox1.InvokeRequired)//判断是否线程安全,如果不安全调用一个委托。
{ D_power d = new D_power(W_Reveive);
this.Invoke(d, new object[] { text });
}
else
{
Scane(text);//这个函数是最后实际处理数据的,此次可以设置为显示数据。
}
}
思路如下:
把想对另一线程中的控件实施的操作放到一个函数中,然后使用delegate代理那个函数,并且在那个函数中加入一个判断,用 InvokeRequired 来判断调用这个函数的线程是否和控件线程处于同一线程中,如果是则直接执行对控件的操作,否则利用该控件的Invoke或BeginInvoke方法来执行这个代理。示例代码如下:
1 using System;
2 using System.Collections.Generic;
3 using System.Windows.Forms;
4
5 using System.Threading;
6
7 namespace 子线程操作主线程窗体上的控件
8 {
9 public partial class frmMain : Form
10 {
11 /********************** 定义该类的私有成员 **************************/
12
13 /// <summary>
14 /// 定义一个队列,用于记录用户创建的线程
15 /// 以便在窗体关闭的时候关闭所有用于创建的线程
16 /// </summary>
17 private List<Thread> ChaosThreadList;
18
19 /********************** 该类的初始化相关函数 ************************/
20
21 /// <summary>
22 /// 窗体的初始化函数,初始化线程队列ChaosThreadList
23 /// </summary>
24 public frmMain()
25 {
26 InitializeComponent();
27 ChaosThreadList = new List<Thread>();
28 }
29
30 /// <summary>
31 /// 窗体的关闭事件处理函数,在该事件中将之前创建的线程全部终止
32 /// </summary>
33 /// <param name="sender"></param>
34 /// <param name="e"></param>
35 private void frmMain_FormClosed(object sender, FormClosedEventArgs e)
36 {
37 if (ChaosThreadList.Count > 0)
38 {
39 //编列自定义队列,将所有线程终止
40 foreach (Thread tWorkingThread in ChaosThreadList)
41 {
42 tWorkingThread.Abort();
43 }
44 }
45 }
46
47 /**************************** 定义该类的自定义函数 ***********************/
48
49 /// <summary>
50 /// 定义一个代理
51 /// </summary>
52 /// <param name="index"></param>
53 /// <param name="MSG"></param>
54 private delegate void DispMSGDelegate(int index,string MSG);
55
56 /// <summary>
57 /// 定义一个函数,用于向窗体上的ListView控件添加内容
58 /// </summary>
59 /// <param name="iIndex"></param>
60 /// <param name="strMsg"></param>
61 private void DispMsg(int iIndex,string strMsg)
62 {
63 if (this.lstMain.InvokeRequired==false) //如果调用该函数的线程和控件lstMain位于同一个线程内
64 {
65 //直接将内容添加到窗体的控件上
66 ListViewItem lvi = new ListViewItem();
67 lvi.SubItems[0].Text = iIndex.ToString();
68 lvi.SubItems.Add(strMsg);
69 this.lstMain.Items.Insert(0, lvi);
70 }
71 else //如果调用该函数的线程和控件lstMain不在同一个线程
72 {
73 //通过使用Invoke的方法,让子线程告诉窗体线程来完成相应的控件操作
74 DispMSGDelegate DMSGD = new DispMSGDelegate(DispMsg);
75
76 //使用控件lstMain的Invoke方法执行DMSGD代理(其类型是DispMSGDelegate)
77 this.lstMain.Invoke(DMSGD, iIndex, strMsg);
78
79 }
80 }
81
82 /// <summary>
83 /// 定义一个线程函数,用于循环向列表中添加数据
84 /// </summary>
85 private void Thread_DisplayMSG()
86 {
87 for (int i = 0; i < 10000; i++)
88 {
89 DispMsg(i + 1, "Welcome you : " + (i + 1).ToString());
90 Thread.Sleep(10);
91 }
92 }
93
94 /******************************* 定义该类的事件处理函数 ********************************/
95
96 /// <summary>
97 /// 【开始】按钮的单击事件处理函数,新建一个线程向窗体上的ListView控件填写内容
98 /// </summary>
99 /// <param name="sender"></param>
100 /// <param name="e"></param>
101 private void btnBegin_Click(object sender, EventArgs e)
102 {
103 //创建一个新的线程
104 Thread tWorkingThread = new Thread(Thread_DisplayMSG);
105
106 //将新建的线程加入到自定义线程队列中,以便在窗体结束时关闭所有的线程
107 ChaosThreadList.Add(tWorkingThread);
108
109 //开启线程
110 tWorkingThread.Start();
111 }
112
113 }
114 }
这样子就可以实现用子线程去操作主线程窗体上的控件的内容,同时,又不影响主线程对窗体上其他控件的响应。
这里有详解http://blog.sina.com.cn/s/blog_5a6f39cf0100s23x.html
卜苇风湿: 请添加下面类为顶级类: public static class CtrlEx { public static void InvokeFocus(this Control c) { if (c.InvokeRequired) { c.Invoke(new Action(InvokeFocus), new object[] { c }); } else { c.Focus(); } } }然后在其他线程中直接调用即可,如this....
义马市13123196010: 如何使用C#的方法 Dispatcher.Invoke => - ?
卜苇风湿: Dispatcher.Invoke的参数是一个委托,会把委托的东西放到界面线程去执行.而() => {}是lamda表达式,可以用来构造一个委托.你去搜下委托和lamda就可以了.
义马市13123196010: C#中Invoke 和 BeginInvoke 的区别 - ?
卜苇风湿: 区别在于Invoke是同步,BeginInvoke是异步. 打个比方(伪代码),后台线程中需要通知UI界面进行刷新new Thread() {/* 比如读取数据库的方法,比较耗时;var data = GetData(); 读取完成后通知UI线程,this.Invoke(data); //如果GetData方法是同步方法,则用Invoke回调//this.BeginInvoke(data); //如果GetData是异步方法,则用BeginInvoke回掉 }
义马市13123196010: c#中如何跨线程调用windows控件 - ?
卜苇风湿: 在辅助线程调用(可通过delegate)下面的方法InvokeControl();//写在主线程中(控件) private void InvokeControl() { if (this.InvokeRequired) this.Invoke(new DelegateChangeText(ChangeText)); else this.ChangeText(); } private void ChangeText() { this.TextBox.Text = "sd"; } public delegate void DelegateChangeText();
义马市13123196010: 在C#多线程中,很多帖子都提到了invoke 和beginInvoke函数?
卜苇风湿: 首先他们都是在线程中执行指定委托的.他们的参数都是delegate invoke在使用的时候你可以看做调用一个函数. begininvoke是在线程中异步执行委托.
义马市13123196010: 怎样从别的线程操作控件(C#语言) - ?
卜苇风湿: 在另外一个线程里操作控件someControl,在这个线程中使用以下方法:if (someControl.InvokeRequired) //这段代码写在后台线程中 {someControl.Invok(( MethodInvoker)delegate { //操作控件的代码 }); }例如,在后台线程中操作窗体上的textBox1 if (textBox1.InvokeRequired) //这段代码写在后台线程中 {textBox1.Invoke(( MethodInvoker)delegate { textBox1.Text ="来自后台线程的信息"; } ); }
义马市13123196010: c# invoke方法 - ?
卜苇风湿: 用BackgroundWorker类来异步执行需要更新UI线程中数据的运算会比较好一些.
义马市13123196010: C#delegate方法invoke和beginInvoke的区别 - ?
卜苇风湿: class Program { delegate void test(); static void Main(string[] args) { test ts = new test(TestDelegate); ts.BeginInvoke(null,null); //使用到委托的beginInvoke方法 Console.WriteLine("hello"); } internal static void TestDelegate() { Thread.Sleep(5000)...
义马市13123196010: C# Parallel.Invoke终止并行的所有线程 - ?
卜苇风湿: 并行代码中,ParallelLoopState提供了两个方法:break和stop; Break()是通知并行计算尽快的退出循环; Stop()是所有线程全部退出. 这里Stop()方法符合你的问题. Parallel.For(0, Count, (i, state) =>{if (条件){state.Stop();return;}});