后台线程 mfc AfxBeginThread创建函数或者对象中的静态函数 dotnet Task.Run或者new Thread ui线程 mfc 继承CWinThread、给子类绑定dialog ,窗口在独立的线程中初始化和析构。 virtual BOOL InitInstance(); virtual int ExitInstance(); protected: DECLARE_MESSAGE_MAP() }; dotnet 在线程中创建的 ui属于本线程资源不能跨线程使用
vs2005中,子线程不允许使用UI中的控件,网上的解决方法都有:使用控件的Invoke,不过在我自己的应用中总觉得麻烦:我要从子线程中调用一个主线程中的处理,要用一次委托,而Invoke还要用委托, 我稍微改了一下结构,可以比较方便的达到在子线程中调用UI线程中的处理函数。 主要是利用它回到UI线程 public ReceivedHandlerUI OnReceivedUI; //接收处理函数,涉及UI public System.Windows.Forms.Control ), this); //界面处理 void MyReceivedHandlerUI(object obj) { LineInfo li = (LineInfo)obj; textBox2. 同时,由于是在UI线程中执行,所以操作控件时也不用考虑并发性线程安全之类的。
大家都知道,不可以在 其他线程访问 UI 线程,访问 UI 线程包括给 依赖属性设置值、读取依赖属性、调用方法(如果方法里面修改了依赖属性)等。 一旦访问UI线程,那么就会报错,为了解决这个问题,需要使用本文的方法,让后台线程访问 UI 线程。 本文提供三个方法可以让其他线程访问 UI 线程 第一个方法是比较不推荐使用的,可能出现 win10 uwp Window.Current.Dispatcher中Current为null 请不要在这里使用 High ,一般都是使用比较低的优先 为何不设置为 High ,参见 CoreDispatcherPriority 那么比较推荐的一个方法是在一个用户控件或者Page之类的,如果在里面使用了异步线程需要访问 ui 的属性,那么可以使用下面代码 await Dispatcher.RunAsync(Windows.UI.Core.CoreDispatcherPriority.Normal, () => {
大家都知道,不可以在 其他线程访问 UI 线程,访问 UI 线程包括给 依赖属性设置值、读取依赖属性、调用方法(如果方法里面修改了依赖属性)等。 一旦访问UI线程,那么就会报错,为了解决这个问题,需要使用本文的方法,让后台线程访问 UI 线程。 本文提供三个方法可以让其他线程访问 UI 线程 第一个方法是比较不推荐使用的,可能出现 win10 uwp Window.Current.Dispatcher中Current为null 请不要在这里使用 High ,一般都是使用比较低的优先 为何不设置为 High ,参见 CoreDispatcherPriority 那么比较推荐的一个方法是在一个用户控件或者Page之类的,如果在里面使用了异步线程需要访问 ui 的属性,那么可以使用下面代码 await Dispatcher.RunAsync(Windows.UI.Core.CoreDispatcherPriority.Normal, () => {
由于项目中存在这样的载入的画面:在界面上有显示载入信息的Label控件和进度条,如果采用单线程则在载入数据的时候UI界面会被锁死,造成假死的感觉。 为了给一个更友好的界面,因此有必要引入多线程技术,使得软件更加“人性化”。 但随后在子线程中访问界面上的控件的时候会出现异常,不能操作主线程所控制的UI界面。看来这得用到委托技术了! 定义线程: ThreadStart ts = new ThreadStart(Downin); //括号里面的参数是一个方法名,表示线程要处理的方法 Thread mythread = new Thread(ts); mythread.Start(); //线程开始运作 以上三行是线程操作的核心内容,不熟悉线程定义和执行原理等的园友请参考《C#线程参考手册》! 本文只是抛砖引玉,可以了解一下线程和委托的好处。当然,线程并不是越多越好,否则只会增加系统开销,应该看实际需要来应用。 注:如有疏漏之处请指教,谢谢。
TextView android:text="X" /> <TextView android:layout_span="<em>2</em>" </TableRow> d) 在首列中不能够放弃首列,那么在这一行的其次列中设置"layout_column='1'",他就变成了首列了 "layout_span=2" 1、ScrollView和HorizontalScrollView是为控件或者布局添加滚动条 2、上述两个控件只能有一个孩子,但是它并不是传统意义上的容器,但是可以不跟布局,如LinearLayout写它里面 ) getSystemService(LAYOUT_INFLATER_SERVICE);// View v3 = inflater2.inflate(R.layout.item_listview, = new HashMap<String, Object>(); map2.put("photo", R.drawable.photo2); map2.put("name", "小志"); data.add
例如,按钮点击、页面滚动、元素大小改变等操作都会触发 UI 更新。UI线程的效率直接影响到页面的响应速度和流畅度。如果在 UI 线程上执行耗时操作,会导致界面卡顿,用户体验下降。2. 三、UI线程与JS线程的协作与瓶颈UI线程与JS线程的分离使得它们各自承担不同的任务,但也存在协作瓶颈。 例如,JS线程的执行和UI线程的渲染是互相影响的:JS线程处理完数据后,UI线程需要更新界面;而UI线程在渲染时,如果长时间占用线程,也会影响JS线程的任务执行。1. 尤其在页面渲染过程中,有多个复杂的计算和 DOM 更新时,UI线程可能会被阻塞,造成界面卡顿。2. 事件回调的阻塞在小程序中,很多事件(如点击、滑动等)都会触发JS线程中的事件处理函数。 '); }, 0); // 使用 setTimeout 推迟执行,释放UI线程}fetchData();2.
前言 这是一个初级Android工程师面试问题,一般标准答案:子线程不能操作UI控件。 那我为什么还要问这个弱智的问题呢? 因为我心目中的标准答案:子线程不能操作"参与绘制"的UI控件。 ();//操作3 其实操作1和操作2最终也是调用操作3,操作3才是真正刷新界面的代码。 Thread.currentThread不等于mThread(主线程/UI线程),也就是子线程。 四、什么是参与绘制 看完上面的内容,肯定有人说答案不就是子线程不能操作UI控件嘛,为什么还要加上"参与绘制"的条件。 以上情况就是属于“不参与绘制”的情况 总结 现在应该理解我的标准答案:子线程不能操作"参与绘制"的UI控件。
概述 在Android中,UI线程是一个很重要的概念。我们对UI的更新和一些系统行为,都必须在UI线程(主线程)中进行调用。 在Linux中是没有主线程这一概念的。 那么,如果我们在子线程调用了一个native方法,在C++的代码中,我们想要切换到主线程调用某个方法时,该如何切换线程呢? 只是在调用之前,做了线程的转换,在C++层的主线程调用了toast。 通过初始中的这样两个方法,我们就构建了一条通往主线程的通道。 发往主线程 在初始化的方法中,我们构筑了一条消息通道。接下来,我们就需要将消息发送至主线程。 这样,我们只需要在子线程中,以一定的编码格式向主线程发送消息,即可完成在native中切换主线程的能力。 --- 如有问题,欢迎指正。
本文告诉大家如何在 WPF 使用多线程的 UI 的方法 在很多的时候都是使用单线程的 UI 但是有时候需要做到一个线程完全处理一个耗时的界面就需要将这个线程作为另一个 UI 线程 在 WPF 可以使用 VisualTarget 做到多个 UI 线程的绘制,注意这里的 WPF 的渲染线程只有一个,多个 UI 线程无法让渲染的速度加快。 如果一个界面有很多的 Visual 那么渲染速度也不会因为添加 UI 线程用的时间比原来少 在 WPF 的 VisualTarget 可以用来连接多个不同的线程的 UI 元素,在使用的时候只需要创建,然后在另一个 UI 线程将创建的元素添加到 RootVisual 就可以 var thread = new Thread(() => { UI 线程,创建一个 UI 线程的最简单方法是运行 Dispatcher.Run() 和设置线程 STA 才可以,注意这里的 Dispatcher 是静态类 var thread
所有用于更新用户界面的操作都是由浏览器的UI线程来完成 UI线程维护一个队列,把每个要更新UI的操作都做为一个任务添加到队列中,然后等UI线程空闲时再按顺序进行处理 示例 <button onclick document.createElement("div"); div.innerHTML = "test"; document.body.appendChild(div); } </script> 当用户点击按钮时,会触发UI 线程来创建两个任务,并添加到队列中, 第一个任务是更新按钮的点击状态样式,是浏览器默认的操作 第二个任务是执行 doClick() UI线程空闲下来后,先从队列中取出第一个任务来执行,完成后,再取出第二个任务 ,doClick()中需要创建一个元素并添加到body,这也是一个更新UI的操作,UI线程会再创建一个任务并添加到队列中,然后在UI线程空闲后再次从队列中取出任务来执行 ?
进入正题,大家应该都听过这样一句话——“UI更新要在主线程,子线程更新UI会崩溃”。久而久之就感觉这是个真理,甚至被认为是“官方结论”。 但是如果问你,官方什么时候在哪里说过这句话,你会不会有点懵。 { btn_ui.text="年轻人要讲武德" } } 2)onCreate方法中更新了按钮显示文字,加了延时。 检查线程,其实就是检查更新UI操作的当前线程是不是当初创建UI的那个线程,这样就保证了线程安全,因为UI控件本身不是线程安全的,但是加锁又显得太重,会降低View加载效率,毕竟是跟交互相关的。 总结 任何线程都可以更新UI,也都有更新UI导致崩溃的可能。 其中的关键就是view被绘制到界面时候的线程(也就是最顶层ViewRootImpl被创建时候的线程)和进行UI更新时候的线程是不是同一个线程,如果不是就会报错。
UI,没有用handler切到主线程,就会报这个错。 那为啥 子线程更新UI没报错,主线程报错呢? 一般情况,UI就是指Activity的view,这也是我们通常称主线程为UI线程的原因,其实严谨叫法应该是activity的UI线程。而我们这个例子中,这个子线程也可以称为button的UI线程。 根据handler的相关知识: 因为UI控件不是线程安全的。那为啥不加锁呢?一是加锁会让UI访问变得复杂;二是加锁会降低UI访问效率,会阻塞一些线程访问UI。 另外注意2,在activity的onCreate到首次onResume的时期,创建子线程在其中更新UI也是可以的。这不是违背上面的结论了吗?
AutoRefreshListView开始,那先来了解下一般使用ListView的步骤: 布局器寻找ListView控件,通过findViewById方法 创建数据适配器 ListView设置数据适配器与常用事件 新增数据到适配器并更新UI 但是数据更新到UI,会遇到多种不同数据结构(多种消息类型),那么能不能找到一种简洁的方法,让不同消息交给不同的消息处理者,以此来达到解耦的目的。 1.1如何获取provider对象 贴上获取provider代码,讲下基本的思路: 1.判断消息是否是评论消息,如果不是,则根据消息类型获取对应消息类型的provider; 2.如果provider为null ; } this.mInflateView = result; return result; } } 2. inflate方法,根据传入的消息处理者类型,如果mContentViewMap中存在了对应控件,mViewCounterMap找到对应键并自动+1(这里的键的类型是AtomicInteger,自增或者自是减线程安全的
这个时候我们需要把这些耗时的操作,放在一个子线程中,因为子线程涉及到UI更新,Android主线程是线程不安全的,更新UI只能在主线程中更新.。 Runnable (2)在子线程中发送一个消息,在主线程中检测该消息处理 线程间传递Message对象的sendMessage方法和发送Runnable多线程对象的post方法。 正对应着上面所说的两个特性1)、2) 下面开发个Handler实例做说明: 用post的方法执行一个Runnable对象,在该对象中随机产生一个10~100之间的随机数,赋值到UI主线程中的TextView 在里面还有个handler对象,这又涉及到了跨线程修改UI元素内容的问题。在java中是不允许跨线程修改UI元素的,如我们在新启动的线程中想去修改UI主线程中TextView的文本时,会报错误的。 2) 异步调用的方法 AsyncTask 这里关于AsyncTask 介绍的文章不错, 详细情况看作者的介绍吧 :Click Here 接下来也将会有一篇博客专门介绍 关于更新主线程UI线程的所有办法
工作线程(耗时操作)与UI线程实现异步更新 概述:工作线程A(多任务)执行期间,把单一任务的结果返回到UI线程更新。 实现: 创建基础流程类(两个handler) public abstract class BaseQueueThread { /** * 设置处理线程、ui处理流程,由子类实现 protected abstract Object doInWork(int integer);//耗时操作 protected abstract void doInUi(Object obj);//更新ui ;i++) { easyQueueThread.sendMessage(i,i); } } } 3.总结:耗时操作不要放在UI 线程,关键点要处理好什么时候执行工作线程,什么时候执行UI线程。
但是我们知道大部分UI框架(比如SWT)都要区分UI线程和非UI线程,如果Observable对象在非UI线程执行notifyObservers操作,而Observer的update方法又涉及UI对象的操作时就会抛出异常 (参见 《SWT的UI线程和非UI线程》)
如果Observer的代码不用关心自己是不是在UI线程,就可以降低Observer代码的复杂度,所以为解决这个问题,我对Observable做了进一步封装。 线程/非UI线程的透明化调用
* @author guyadong
*
*/
public class SWTObservable extends Observable {
/** * {@link Observer}在SWT环境下的重新封装
* 实现UI/非UI线程透明化
* @author guyadong
*
*/
class 线程和非UI线程》http://blog.csdn.net/dollyn/article/details/38582743
C#中跨线程访问UI dotnet中线程资源独占UI元素,不能跨线程访问,可以通过Dispatcher.Invoke的方式调用,但实际处理还是UI线程中,任务量比较大的数据会增加线程的处理压力 其实还有一种做法,可以通过设置UI元素为只读的方式,跨线程访问。 如BitmapSource跨线程访问,可以调用Freeze设置元素为只读模式。 Aforge.net跨线程传递图像资源,如下: private void Cam_NewFrame(object sender, AForge.Video.NewFrameEventArgs eventArgs
1.2卡顿因素 导致卡顿的因素有很多,常见有: UI线程中的耗时操作 复杂、不合理的布局以及过度绘制 内存使用异常导致频繁GC 错误的异步实现 以上四条中,最主要的卡顿原因为UI线程中执行耗时操作。 我们也一直在研究,在不影响京东App性能的前提下,完美的实现一个UI线程卡顿监控系统。该系统能够监控线上用户的卡顿,上报卡顿数据,数据聚合,根据聚合结果自动生成工单,将工单发给对应模块的负责人。 2、主线程卡顿收集SDK实现 2.1 监控原理 1.主线程只有一个looper Looper.java的源码可以看到,定义了一个静态变量sMainLooper,主线程无论有多少个Handler,但只有这一个 主线程:发生卡顿后需要从采样线程的对象池中将属于T2-T1时间段的堆栈等采样信息保存起来,将数据传递给缓存池。 2、 getMainPrinter():Looper中并没有提供获得主线程Printer的方法。
pshared, unsigned int __value) __THROW; __sem 指向信号量结构的一个指针 __pshared 不为0时此信号量在进程间共享,否则只能为当前进程的所有线程共享 __newthread 指向线程标识符的指针 __attr 设置线程属性,一般配置为NULL (*__start_routine) (void *) 线程运行函数的起始地址 __arg 运行函数的参数 with __THROW. */ extern int pthread_join (pthread_t __th, void **__thread_return); 调用它的函数将一直等待到被等待的线程结束为止 ,当函数返回时,被等待线程的资源被收回 __th 被等待的线程标识符 __thread_return 为一个用户定义的指针,它可以用来存储被等待线程的返回值 ---- sem_wait semaphore.h 信号量的值没有更改,-1 被返回,并设置errno 来指明错误 EINVAL sem 不是一个有效的信号量 EOVERFLOW 信号量允许的最大值将要被超过 ---- 总结 以下函数可以进行信号量和线程的创建与控制