c# 跨子线程更新ui 读取 主子线程更新uiUI界面上的控件属性值应该怎么编写程序?

有人编写过C#跨类跨线程调用控件的么有的加我下QQ必有重谢啊_百度知道
提问者采纳
QQ公司不让上,我刚做的一个项目跨线程访问控件的模块就是我做的你是遇到了&线程间操作无效&这个问题吧?
可以用百度的聊天聊么,MSN实在是很垃圾,我下了个半天加上了你就是发不了信息,无语
说说 你遇到了什么问题?有可能我也遇到过,最好贴出来代码
就是我在我在FORM类里面调用了另一个类里面的方法,这个方法又掉用了本类里面的线程,这个线程中会掉用到控件,我看过控件的属性是变了,但是界面不显示为什么?
你在你的那个线程中更改控件属性的方法是用委托更改的么?能不能把代码贴出来?
private void button1_Click(object sender, EventArgs e)
threadtcpserver instance = new threadtcpserver();
你写的代码有问题,form1不应该是在那个clientthread这个类里面生成的吧?你要是想修改主线程窗体里的控件属性不应该实例化新的form1实例而是应该为构造函数里创建一个参数来接受你想修改的窗体,你可以这样改代码,你现在的问题不止一个,线程调用是个问题,对象混淆才是你修改后属性变了界面不显示的真正原因。为class clientthread做一个构造函数Form1 _form1;public clientthread(Form1 form1){this._form1=form1;}调用修改控件方法的时候用委托,还要加入一段代码,这段代码是加入到clientthread这个类里的 delegate void SetLabelValu(string s,Label label);
private void SetLabel(string s, Label label)
if (label.InvokeRequired)
SetLabelValu sv = new
SetLabelValu(SetLabel);
box.Invoke(sv,new object[]{s,label});
label.Text=s;
}第三部,修改一下你原来修改属性的代码form1.label5.Text=这句代码转换为SetLabel(data,form1.label5);最后一步,实例化这个类的时候传入窗体参数clientthread ct=new clientthread(this);
您说委托是写在clientthread里面的但是这个类里面是没有Label的调用SetLabel(data,form1.label5);就会报错错误找不到类型或命名空间名称“Label”(是否缺少 using 指令或程序集引用?)
错了是_form1.label5 然后在上面写上using System.Windows.F
_form1.label5如果写成这样就会报错未将对象引用设置到对象的实例。Form1 _form1;public clientthread(Form1 form1){this._form1=form1;}我加到了clientthread类的开始的地方
你实例化的时候怎么写的代码?clientthread ct=new clientthread(this);注意要这样实例化
我是在另外一个类里面的线程对它实例化的Form1 form1=new Form1();
Socket client = server.Accept();
clientthread newclient = new clientthread(client);
clientthread newclient = new clientthread(form1);
Thread newthread = new Thread(new ThreadStart(newclient.clientserver));
newthread.Start();
这啥玩意啊?clientthread newclient = new clientthread(client);这句代码是说明你要传入一个Socket类型的参数,你下面又来了个这个clientthread newclient = new clientthread(form1);我刚看到你这里需要接受参数构造函数这样写Form1 _form1;public clientthread(Socket clientthread,Form1 form1){this._form1=form1;this.server=}然后调用的时候这样 clientthread newclient = new clientthread(client,form1);还有啊,你那个Form1根本就没有show出来。
提问者评价
谢谢您还有楼下的高手
其他类似问题
线程的相关知识
其他2条回答
窗体的函数用委托不就好了吗?例如:public void SetText(string text){
if(this.InvokeRequired) this.Invoke(new Action&string&(SetText), text);
else this.Text=} 另外楼上的,跨线程访问还需要啥跨线程访问模块?
高手您有QQ么,或者什么通讯方式么
可以加群讨论:-------------------------------------------补充一下资料。1.form1没有显示,在构造函数启动新线程之前调用form1.Show()显示;2.加上这个函数:public void SetText(string text){
if(form1.InvokeRequired) form1.Invoke(new Action&string&(SetText), text);
else form1.label5.Text=} 在新线程的那个修改form1属性的地方修改为 SetText(data);3.编码使用的是ASCII编码,出现中文或非英文字符的时候可能会出现问题。4.connection是连接计数?那应该定义为静态变量:static int connect,如果不是静态的,将始终为1.
高手刚才多有得罪对不起,我真的是刚学这个语言所以懂得不多,那个在构造函数启动新线程之前调用form1.Show()显示;那这样我就会有两个窗体同事存在了的
如果不希望多个窗体出现,那就在构造新线程的时候将原始的form对象传递过去,而不是新建一个。但是从你的代码来看新消息来会覆盖掉老的消息,所以你需要考虑一下。另外风闻你是想开发一个聊天软件,其实我有开发过一个开源的飞鸽传书控件库,你可以参考一下。网址在参考资料。
参考资料:
“我看过控件的属性是变了,但是界面不显示为什么?”确认下你看过的‘控件’和你界面那个控件是同一个吗?
等待您来回答
下载知道APP
随时随地咨询
出门在外也不愁InvokeHelper,ASP.NET让跨线程访问 多线程的一些问题_net吧_百度贴吧
&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&签到排名:今日本吧第个签到,本吧因你更精彩,明天继续来努力!
本吧签到人数:0成为超级会员,使用一键签到本月漏签0次!成为超级会员,赠送8张补签卡连续签到:天&&累计签到:天超级会员单次开通12个月以上,赠送连续签到卡3张
关注:8,186贴子:
InvokeHelper,ASP.NET让跨线程访问 多线程的一些问题收藏
事实上,本文内容很简单且浅显,所以取消前戏,直接开始。。源代码:在本文最后这里是一张动画,演示在多线程(无限循环+Thread.Sleep)情况下主界面操作不受影响。
多线程是一种提高程序运行效率和性能的常用技术。随着我们学习工作的深入,在编程中或多或少会涉及到需要多线程的情况。多数时候,我们的操作模式是后台线程中处理数据,计算结果,然后在前台界面(GUI)中更新显示。
在.NET Framework中,为了保证线程安全,避免出现访问竞争等问题,是不允许跨线程访问窗体控件的。如果强行访问,则会引发InvalidOperationException无效操作异常,如下图:为了实现跨线程访问控件,.NET Framework为每个控件提供了InvokeRequired属性和Invoke方法。使用这些技巧,就可以实现我们在其他线程中直接修改界面的需要。看起来似乎很简单,但实际每次调用都有不少代码需要编写,还需要自行处理各种异常。下面是典型的调用例子:public void DoWork()
if (control.InvokeRequired)
control.Invoke(DoWork);
// do work
为了便于使用,我封装了实现细节,在这里给出一个InvokeHelper类,使用该类即可方便地实现跨线程调用主界面控件方法、获取/设置控件属性等功能。该类实现非常简单,有效代码约150行,主要有以下3个方法:1.Invoke该方法可以调用主界面控件的某个方法,并返回方法执行结果。用法如下:InvokeHelper.Invoke(&控件&, "&方法名称&", &参数&);
其中“参数”为参数列表,支持0个或多个参数。2.Get该方法可以获取主界面控件的某个属性。用法如下:InvokeHelper.Get(&控件&, "&属性名称&");
3.Set该方法可以设置主界面控件的某个属性。用法如下:1
InvokeHelper.Set(&控件&, "&属性名称&", &属性值&);
多线程过程中经常会出现“从不是创建控件的线程访问”这个异常!常使用Invoke来解决这个问题,当设计当UI界面的更新时,非UI线程委托UI线程更新当前界面,自己则处于阻塞状态,而BeginInvoke方法解决了这个问题,因为它是异步的
用委托就行了
登录百度帐号我的游戏推荐游戏
后查看最近玩过的游戏
为兴趣而生,贴吧更懂你。或您所在的位置: &
.NET跨线程控件的相关操作
.NET跨线程控件的相关操作
代码的旋律
本文将为大家介绍一下.NET跨线程控件的相关操作,有时可能会出现一种跨线程调用的异常,这里也包括相关的解决方案。
在.NET中,如果我们在非UI线程上访问窗体上的控件的时候,会产生一个跨线程调用的异常,那么如何处理这种情况呢?在上一章中,我介绍了使用Control.Invoke方法,如果你不习惯使用委托,那么.Net还为我们提供了一个组件BackgroundWorker,你可以使用这个组件,以事件的方式去处理这种跨线程的控件访问。下面我就来详细的介绍一下这个组件的用法。
我们先来看一下BackgroundWorker提供了哪些常用的成员,
◆DoWork:我们在这个事件中,执行需要异步处理的工作。
◆ProgressChanged:我们在这个事件中,接收并处理异步处理过程中的信息。
◆RunWorkerCompleted:我们在这个事件中,执行异步处理结束的工作。
◆RunWorkerAsync()和RunWorkerAsync(object argument):这两个方法触发DoWork事件,开始异步操作。
◆ReportProgress(int percentProgress)和ReportProgress(int percentProgress, object userState):这两个方法触发ProgressChanged事件。
◆CancelAsync:结束后台的异步操作。
◆bool CancellationPending:指示当前的后台的异步操作是否正在被取消,执行CancelAsync方法会导致这个属性为true。
◆bool IsBusy:指示当前的后台异步操作是否正在进行,进行中为true。
◆bool WorkerReportsProgress:获取或设置当前的BackgroundWorker是否可以执行ProgressChanged方法。
◆bool WorkerSupportsCancellation:获取或设置当前的BackgroundWorker是否可以执行CancelAsync方法。
OK,有了上面这些成员,我们来看一下BackgroundWorker是如何工作的。
Step 1. 当然是定义一个BackgroundWorker的实例,你可以从工具箱中拖拽一个BackgroundWorker控件到窗体上或者在代码中直接声明;
Step 2. 生成DoWork事件并在DoWork事件的中添加需要异步执行的代码。在异步执行的代码中,如果需要处理界面中的控件,请调用ReportProgress方法,而不要直接处理(例如给控件赋值),因为DoWork事件跟正常的界面的事件不同,这个事件在非UI线程上执行,所以才能异步执行。
Step 3. 生成ProgressChanged事件并添加控件处理的代码,因为这个事件是在UI线程上执行的,所以可以给界面中的控件进行赋值等操作。
Step 4. 如果需要,请生成RunWorkerCompleted事件,在此处理异步执行结束的业务逻辑。当然,此事件也是在UI线程上执行的,可以给界面中的控件进行赋值等操作。
Step 5. 在需要执行异步操作的地方调用RunWorkerAsync方法,开始执行异步调用。
下面是具体的代码:
public&Form1()&&& &&{&&& &&&&InitializeComponent();&& &&&&&&bWorker.DoWork&+=&new&DoWorkEventHandler(bWorker_DoWork);&& &&&&&&bWorker.RunWorkerCompleted&+=&new&RunWorkerCompletedEventHandler(bWorker_RunWorkerCompleted);& &&&&&&bWorker.ProgressChanged&+=&new&ProgressChangedEventHandler(bWorker_ProgressChanged);&&& &&&&this.Text&=&&UI&thread&id&is:&&+&Thread.CurrentThread.ManagedThreadId.ToString();&&& &&}&&& &BackgroundWorker&bWorker&=&new&BackgroundWorker();&& &void&bWorker_DoWork(object&sender,&DoWorkEventArgs&e)&& &&{&& &&int&tick&=&(int)e.A&& &&&Thread&thr&=&Thread.CurrentT&& &&for&(int&i&=&0;&i&&&30;&i++)&& &&&{&& &&&&&if&(bWorker.CancellationPending)&& &&&&&&{&& &&&&&&&&&e.Cancel&=&true;&& &&&&&&&&&&&&&&&}&& &&else&& &&&&&{&& &&&&&&&&&&&&Thread.Sleep(TimeSpan.FromSeconds(tick));&& &&&&&&&&&&&bWorker.ReportProgress(i,&DateTime.Now.ToString()&+&&\\TID:&&+&thr.ManagedThreadId.ToString());&& &&&&&&&}&& &&&&&}&& &&&&&& &&}& &void&bWorker_ProgressChanged(object&sender,&ProgressChangedEventArgs&e)&& &&{&& &progressBar1.Value&=&e.ProgressP &&&&&&label1.Text&=&e.UserState.ToString();& &&}&& &void&bWorker_RunWorkerCompleted(object&sender,&RunWorkerCompletedEventArgs&e) &&{&& &&label1.Text&=&DateTime.Now.ToString();& &&&&&&progressBar1.Value&=&progressBar1.M&& &&&&&&if&(e.Cancelled)&& &&label1.Text&=&&User&cancelled.&;&& &}&& &private&void&btnInvoke_Click(object&sender,&EventArgs&e)& &{& &&&bWorker.WorkerReportsProgress&=&true;& &&&&&bWorker.WorkerSupportsCancellation&=&true;&& &&&&&if&(!bWorker.IsBusy)& &&&&&&bWorker.RunWorkerAsync(1);&& &}& &private&void&btnCancel_Click(object&sender,&EventArgs&e)&& &&{&& &&&&&if&(bWorker.WorkerSupportsCancellation)& &&&&&&&&&bWorker.CancelAsync();&& &}&
上面的代码请注意几个地方:
1. 第50行,开始调用RunWorkerAsync方法前,请先判断IsBusy属性是否是false,因为如果为true,则说明上一次的调用还没有结束,再次调用会引发异常。
2. 第56行,调用CancelAsync方法前,请先设置WorkerSupportsCancellation属性为true,否则会引发异常。
3. 第26行,调用ReportProgress方法前,请先设置WorkerReportsProgress属性为true,否则会引发异常。
4. RunWorkerAsync方法传递的参数是object类型,这个参数的值可以在DoWork事件的参数e中的属性Argument获得。
5. ReportProgress方法传递的参数可以在事件ProgressChanged中的参数e中获得。
6. 调用CancelAsync方法只是向后台的异步线程发出结束申请,具体什么时候结束,由线程自动管理。
7. 在RunWorkerCompleted事件中,如果想知道后台任务是正常执行完毕还是被调用CancelAsync方法强制中断,请参考事件的参数e的Cancelled属性。(奇怪的是这个属性不会在你调用CancelAsync方法后自动设置为true,你需要象代码中的20行那样进行设置。)
8. 请注意第7行和第26行的代码,这两段代码中的线程的ID,说明了DoWork事件和UI是在两个不同的线程上执行。
实际上BackgroundWorker并非直接用来解决跨线程的控件调用的问题,只是它提供了一种工作机制,可以让你的程序利用它来执行异步调用,并且在异步调用的过程中进行控件的操作。
好了,关于如何对界面中的控件进行跨线程的调用就介绍这么多吧,希望对大家有所帮助。
原文标题:&在.Net中进行跨线程的控件操作(下篇:BackgroundWorker)
链接:/happinessCodes/archive//1783199.html
【编辑推荐】
【责任编辑: TEL:(010)】
关于的更多文章
Angular.js 是一个MV*(Model-View-Whatever,不管是MVC或者MVVM
本次的专刊为大家提供了Oracle最新推出的Java SE 8详细的开发教程,从解读到探究Java 8最新
9月的工作日被法定假日拆的零零散散,不知道各位的工
总结一下Java I/O文件读写基本类相关知识和概念。对于
今天是被国际上众多科技公司和软件企业承认的业内人士
本书根据教育部考试中心2004年最新发布的《全国计算机等级考试大纲》编写,针对计算机等级考试三级网络技术各方面的考点进行讲解
51CTO旗下网站

我要回帖

更多关于 android ui 控件 的文章

 

随机推荐