nanui for winformm中遇见ui操作卡顿一般怎么处理解决

C# winform程序,UI界面锁死。如何处理?_百度知道不得不说随着移动市场的逐步成熟,越来越多的“IP”被融入到我们的生活之中。各种“方...
苹果 iPhone 7 的预约跟其他手机厂商不同的是,这个预约要付全款的,另外苹果限定每位...
黑色iPhone 7秉承了苹果追求质感的原则,甚至可以说比其他颜色更有质感,有点像钢琴烤...
说了这么多其实就是想告诉你们:买买买!
本周五就可以预定 Apple Watch Series 2 了,价格 2888 元人民币起售,女神范满满的精...
不过稍显遗憾的是,并未推出iPhone 7的版本。
或许这将是全球首款内置DAC(数字模拟转换器)和LAM模块(lightning audio module)的...
很显然,三星希望Note 7召回这件事迅速“翻篇儿”。
在浩瀚无垠的宇宙中人们可以天马行空的放飞自己的想象力,什么故事、剧情都可以在宇宙...
动人的剧情,精良的音效,渐渐浮出水面的谜团,还算比较好看的画面,《淹没》其实可以...
曾经开发过《风雨世界(The Whispered World)》、《德波尼亚(Deponia)》等佳作的游...
近日,著名游戏开发商麒麟狗(Chillingo)在苹果商店当中推出了其休闲新作《眩晕赛车...
文字、图片、链接、声音,我们在日常生活中接触到的信息是如此的多种多样,而要想将这...
曾经开发过《战龟(War Tortoise)》、《一切尽失(All is Lost)》等多部实力作品的...
本周,游戏开发商Crescent Moon Games在苹果商店当中推出了其制作的休闲新作《原子超...
不过稍显遗憾的是,并未推出iPhone 7的版本。
或许这将是全球首款内置DAC(数字模拟转换器)和LAM模块(lightning audio module)的...
这款产品能够将 iPhone 7 手机上的 Lightning 接口变成两个,可以在听音乐的同时给手...
有观点认为,苹果此次大举进军无线耳机只不过是为了“勇敢地”开辟一块新的赚钱的沃土...
其实说了这么多话,归根结底还是三个字:买买买!
与耳机孔防尘塞不同的是,设计师希望 iPhone 6s 能完全模拟出 iPhone 7 取消了 3.5mm ...
这些配件有基座、有电池背壳,当然还有手机壳。
苹果已经对设备的防水功能做了详细说明,你可以在苹果说明的范围内任性。
UI动画卡顿的可以来试试
注册时间 最后登录
在线时间497 小时 UID
主题帖子人气
白苹果, 积分 596, 距离下一级还需 904 积分
1. finder-前往-~/Library/Preferences/ByHost-删除com.apple.windowserver开头的文件(我电脑上是com.apple.windowserver.80E5DEFA-9FB7-5F18-BE33-FE73)
2.finder-前往-/Library/Preferences/-删除com.apple.windowserver.plist文件
3.重置 NVRAM (官网链接)
至此,UI卡顿会得到稍微改善。
注册时间 最后登录
在线时间497 小时 UID
主题帖子人气
注意第一第二步目录不一样,一个带波浪一个不带。
我本子是初代15寸Retina低配。
hd4000集显状态UI卡顿明显,比如全屏最适应大小等等动画。650m独显倒是很流畅。
这样操作完后即使是集显也没有那么明显的卡顿了。不过finder文件较多的时候最适应大小还是会卡顿。
大概只有Retina屏幕才有效,Air应该没有卡顿现象。
注册时间 最后登录
在线时间497 小时 UID
主题帖子人气
开机关机慢的可以试试系统偏好设置-启动磁盘-(硬盘名称默认应该是Macintosh)-重新启动
注册时间 最后登录
在线时间380 小时 UID
主题帖子人气
注册时间 最后登录
在线时间192 小时 UID
主题帖子人气
第一个解决动画卡顿的原理是啥呢?
注册时间 最后登录
在线时间1350 小时 UID
主题帖子人气
注册时间 最后登录
在线时间497 小时 UID
主题帖子人气
第一个解决动画卡顿的原理是啥呢?
不懂,google搜索ui lag with retina查到的
威锋旗下产品
Hi~我是威威!
沪公网安备 29号 | 沪ICP备号-1
新三板上市公司威锋科技(836555)
增值电信业务经营许可证:
Powered by Discuz!CPU卡顿怎么解?13步教你轻松搞定UI优化
CPU卡顿怎么解?13步教你轻松搞定UI优化
博尔特以9.58秒创造了百米世界纪录,假设他是跑酷游戏的角色,卡顿一帧就足以把冠军拱手让人。 Unity3D程序各项性能问题,从Profiler可观察到许多蛛丝马迹。下面看几个典型例子Profiler的CPU指标截图。 有时候蛛丝马迹非常显眼,闪瞎钛白金像素眼。然而有些过于显眼,以至于Profiler都展开不了看详情。囧。[UICamera.Update]有时候要展开很多很多很多...层才能抓住元凶。[UICamera.Update.xxx.xxx.xxx..........GameObject.SetActive]CPU曲线有偶发性卡顿,比如:[UIPanel.LateUpdate...FillAllDrawCall]CPU曲线也有持续性卡顿,比如:[UIPanel.LateUpdate...FillDrawCall]游戏单局内每一帧都很关键,卡顿轻则引起操作失误,重则直接撞死。边优化边记录,发现UI原因导致卡顿如下表所列。个别类型频繁亮相。序号操作引发问题处理方案①实时加载资源Resource.Load预加载②实时分配内存Instantiate预先分配③显示与隐藏GameObject.SetActive调整为其他等效方式④UIWIdget子类设置color、alpha、depth、position、rotation、scale、width、height、rawPivot、pivotUIPanel.LateUpdate.FillDrawCall或FillAllDrawCall重点处理触发FillAllDrawCall的情况⑤UIBasicSprite子类设置flip、fillDirection、fillAmount、invert触发UIWIdget.MaskAsChange,问题同④方案同④⑥UISprite设置atlas、spriteName、fillCenter触发UIWIdget.MaskAsChange,问题同④方案同④⑦UITexture设置mainTexture、material、shader、border、uvRect触发UIWIdget.MaskAsChange,问题同④方案同④⑧UILabel设置text、font、material、fontSize、fontStyle等一系列属性触发UIWIdget.MaskAsChange,问题同④。text值变更还会触发Font.CacheFontForText,需特别关注,真机耗时明显。方案同④,且避免耗时Font.CacheFontForText⑨重复赋值多个关联UIWIdget组件多次刷新不同UIWIdget组件的各项值合并赋值⑩图标位置重排触发UIGrid. Reposition调整为其他等价方式?同一帧逻辑繁重CPU耗时不平滑分帧处理,或延迟处理?ParticleSystem粒子特效与Animation动画占用CPU资源调整策略,或调整为其他方式注:UILabel、UITexture、UISprite都是UIWidget子类,而UIWidget是UIRect子类。 下文举例阐述表格中各种问题与处理方案详情。游戏项目中实际逻辑代码较为复杂,例子中或以Sample代码示意。 ①实时加载资源问题描述:Resource.Load示意代码Profiler调用节点类似下图所示。(上图借用其他界面某个瞬间截图)处理方案:预加载。资源加载不可避免,但触发时机可以提前,也即提早加载资源,比如脚本Start()或OnEnable(),而不是游戏单局中由玩家输入实时触发。 ②创建实例分配内存问题描述:Instantiate示意代码Profiler调用节点类似下图所示。(上图借用其他界面某个瞬间截图)处理方案:预先分配内存。同①,提早分配所需内存,避免实时触发。 ③显示与隐藏问题描述:显示或隐藏物件,常规思路是采用GameObject.SetActive(true/false),然而此方法会触发一系列UIRect子类的初始化方法。Profiler调用节点类似下图所示。处理方案:应避免直接使用GameObject.SetActive(true/false)显示或隐藏物件,改为其他方式代替。比如设置Position把物件移进移出屏幕,或者设置Scale缩放比例、设置Alpha透明度等方式代替。 ④设置UIWIdget属性问题描述:变更UIWidget(UIRect)及其子类属性,包括alpha、color、depth、localPosition、localRotation、localScale、width、height、rawPivot、pivot,会触发UIPanel.LateUpdate.FillDrawCall或FillAllDrawCall。属性描述alpha透明度。1不透明,0全透明。colorRGB颜色值depth组件层级localPositionxyz坐标localRotationxyz旋转localScalexyz缩放width宽度height高度rawPivot中心点,变更时不变更transformpivot中心点,变更同时变更transform在UIPanel.LateUpdate代码中可看到,若UIWidget(UIRect)的depth、material、mainTexture变更,一定条件下会重排UIWdiget组件渲染顺序,调用FillAllDrawCall或FillDrawCall。Profiler调用节点类似下图所示。可看到FillAllDrawCall明显比FillDrawCall更耗资源。处理方案:单局游戏中应避免变更UIWdiget的depth次序,或变更UIWdiget所用的material、mainTexture,为达到同样的界面显示效果,可以采用变更UIWdiget其他属性来达到相同目的。除了depth调整可能触发FillAllDrawCall,其他属性变更并不会触发FillAllDrawCall。例(1):调整position代替调整depth,达到完全显示与遮挡的特殊切换效果。 ⑤设置UIBasicSprite属性问题描述:UIBasicSprite继承于UIWidget,除UIWidget属性外,UIBasicSprite自身属性字段包括flip、fillDirection、fillAmount、invert。变更属性值会调用UIWIdget.MaskAsChange,可能触发UIPanel.LateUpdate.FillDrawCall或FillAllDrawCall。问题同④。属性描述flip翻转方式fillDirection填充方式fillAmount填充百分比invert是否反方向一般来说UIBasicSprite这几个属性值变更并不会引发FillAllDrawCall。处理方案:同④,根据实际情况处理。 ⑥设置UISprite属性问题描述:UISprite继承于UIBasicSprite,除UIBasicSprite属性外,UISprite自身属性字段包括atlas、spriteName、fillCenter。变更属性值会调用UIWIdget.MaskAsChange,可能触发UIPanel.LateUpdate.FillDrawCall或FillAllDrawCall。问题同⑤。属性描述atlas所在图集spriteName图集中图片名fillCenter是否填充注意,变更atlas会变更mainTexture,进而触发FillAllDrawCall。变更atlas的常见应用场景是因游戏逻辑而实时变更图标。处理方案:为了避免因atlas变更而触发FillAllDrawCall,有几个思路:(1)prefab预先创建多个UISprite并设置对应的atlas和spriteName,在实际显示时再通过变更position来达到相同目的。(2)整合多张Atlas为一张大的Atlas,在实际显示时只切换spriteName。 ⑦设置UITexture 属性问题描述:UITexture继承于UIBasicSprite,除UIBasicSprite属性外,UITexture自身属性字段包括mainTexture、material、shader、border、uvRect。变更属性值会调用UIWIdget.MaskAsChange,进而可能触发UIPanel.LateUpdate.FillDrawCall或FillAllDrawCall。问题同⑤。属性描述mainTexture渲染的Texture。material渲染的Material。shader渲染的Shader。border四个角的坐标uvRectuv值处理方案:为了避免触发FillAllDrawCall,应尽量避免变更属性值。一般来讲,固定不变的贴图才适合使用UITexture。注意,UITexture有一个特殊应用场景是玩家头像。这是因为头像图片是网络下载的资源,默认仅适合UITexture显示。于是变更mainTexture即带来FillAllDrawCall。基于此问题,项目中采用了“动态生成Atlas,游戏中仅切换spriteName”的方案来解决。此Atlas图集包含了真实玩家头像和NPC头像,于游戏开始前动态生成。参考:http://blog.csdn.net/u/article/details/ ⑧设置UILabel属性属性描述text内容。font字体,包括bitmapFont和trueTypeFont。material字体所用Material。fontSize字号fontStyle字体样式:斜体和加粗。其他基础属性同上问题描述:UILabel继承于UIWidget,除UIWidget属性外,UILabel自身属性字段很多,其中text和font需重点关注。(1)text:赋值会带来一系列字符串操作,相对较耗时。此外需特别留意的是,text赋值还会触发Font.CacheFontForText,此方法在真机的实际占用资源比编辑器多很多,实践中应以真机Profiler为准。以下分别是编辑器(0.06ms/0.21ms)和真机(2.12ms/2.39ms)的消耗对比。不管数字、英文或是汉字,现象都一样。处理方案:为避免实时触发Font.CacheFontForText,可在游戏开始时把可能出现的字符全部赋值一次给UILabel.text,也即避免提前触发Font.CacheFontForText。这里提前赋值的字符Cache最小单位是单个字符。比如表示奔跑距离的UILabel:即可Cache全部阿拉伯数字加“米”字的展示需求。(2)font:变更会直接把UILabel从UIPanel的UIWidget列表中移除,再添加一个新的。此操作会带来FillAllDrawCall。实践中鲜见动态修改UILabel.font。若确实需要动态切换UILabel.font,可采用切换两个UILabel来代替,而这两个UILabel分别应用了两个不同font。 ⑨重复赋值多个关联UIWIdget组件问题描述:举一个例子。游戏单局内的任务进度条先前实现是使用两个UIProgressBar,分别更新图形进度条(红色框内容)和数字进度栏(蓝色框内容)。当任务进度刷新时,两个UIProgressBar.value会同步刷新。处理方案:经分析,此处相关联的多个UIWidget可合并赋值。数字进度栏(蓝色框内容,更新数字和位置)加上亮光头部(更新位置)算到整个Thumb,这样UIProgressBar.value就只需要更新一次(红色框内容更新时会同步更新蓝色框内容)。 ⑩图标位置重排问题描述:举一个例子。游戏单局内的Buff列表先前实现是使用一个UIGrid,当数量变更时重排UIGrid。当Item数量减少,需gameObject.SetActive(false)或transform.parent=null,才可以让UIGrid正确重排。这使得UIGrid.Reposition相对耗时。处理方案:以其他等价方式代替。由于是固定的0~3个图标Item,所以按情况设置这4种情况的每组Item坐标即可。不显示的设置Position移到屏幕外。此方法可避免UIGrid.Reposition。 ?同一帧逻辑繁重问题描述:看具体例子。现象(1),游戏单局内UI界面某些数据变化不频繁,无需每帧实时刷新。为了节省CPU资源,按经验值可以每6帧处理一次。代码片段如下:游戏单局内Profiler曲线大致如下,可以看到明显有节奏锯齿:现象(1)处理方案,将耗时逻辑分散到这6帧处理,每帧处理不同逻辑。也即分散了CPU压力。代码片段如下:调整后Profiler曲线大致如下,看到锯齿有所缓解。由于拆分后每一帧的逻辑复杂程度不一样,所以曲线平滑程度有限,仍有改善空间。 现象(2),当游戏单局内触发某类事件,会立即在UI界面上表现。比如捡到一个道具,UI界面立即显示一个图标。代码片段如下:从Profiler看到是同一帧处理了多个耗时逻辑。现象(2)处理方案:延迟处理。将UI表现逻辑延后一帧再处理,分散CPU压力。代码片段如下:调整后Profiler曲线大致如下(下图分别是两帧数据),相对修改前能稍微缓和曲线峰值。 ?ParticleSystem粒子特效与Animation动画问题描述:游戏中为达到酷炫效果,往往会应用ParticleSystem粒子特效与Animation动画,然而此举较耗CPU资源。当游戏单局内场景帧率要求较高时,较多或较复杂的粒子特效和动画会降低帧率,反而影响游戏体验。处理方案:有以下思路,需取折衷方案。(1)调整显示策略。例如:根据高端机、中端机、低端机(根据CPU、运行内存、屏幕分辨率等参数计算的综合性能评分)来决定是否启动特效和动画。(2)以其他等效方式代替。例如:一个图标渐显渐隐同时放大缩小的效果,可采用组合TweenAlpha+TweenScale动画来代替Animation动画。 ?其他除前文提到Unity自带强大Profiler(),实践中还有很多调试工具和方法。比如:(1)强制暂停Unity编辑器。(2)关键节点代码采用return、continue等中断正常流程,以排除法逐渐逼近目标。尤其适用于Profiler展开失败的情况。(3)构建Development Build调试版本,连接真机Profiler:http://blog.csdn.net/u/article/details/
发表评论:
TA的最新馆藏[转]&using System.T
using System.Windows.F
namespace ThreadTest
public partial class Form1 : Form
public Form1()
InitializeComponent();
Control.CheckForIllegalCrossThreadCalls =//这一行是关键
private void btnSet_Click(object sender, EventArgs e)
Thread t = new Thread(new ParameterizedThreadStart(SetTextBoxValue));
t.Start(&Hello World&);
void SetTextBoxValue(object obj)
this.textBox1.Text = obj.ToString();
这种方法是最方便,实现最简单的方式,但是这样等于是线程之间是去了限制,子线程能够直接控制父线程的控件,会出现线程之间的冲突,不是好的实现方式2.利用BackgroundWorkerC# code
using System.Windows.F
namespace ThreadTest
public partial class Form1 : Form
public Form1()
InitializeComponent();
private void btnSet_Click(object sender, EventArgs e)
//MessageBox.Show(Thread.CurrentThread.ManagedThreadId.ToString());
using (BackgroundWorker bw = new BackgroundWorker())
bw.RunWorkerCompleted += new RunWorkerCompletedEventHandler(bw_RunWorkerCompleted);
bw.DoWork += new DoWorkEventHandler(bw_DoWork);
bw.RunWorkerAsync(&Hello World&);
void bw_DoWork(object sender, DoWorkEventArgs e)
//MessageBox.Show(Thread.CurrentThread.ManagedThreadId.ToString());
e.Result = e.A//这里只是简单的把参数当做结果返回,当然您也可以在这里做复杂的处理后,再返回自己想要的结果(这里的操作是在另一个线程上完成的)
void bw_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
//这时后台线程已经完成,并返回了主线程,所以可以直接使用UI控件了
this.textBox1.Text = e.Result.ToString();
//MessageBox.Show(Thread.CurrentThread.ManagedThreadId.ToString());
这种方式只能在异步结束后给控件赋值,--即bw_DoWork是异步处理,异步处理过程中不能给控件赋值--bw_RunWorkerCompleted方法中可以给控件赋值,可是这个过程不是异步的,如果在bw_RunWorkerCompleted中加上一个System.Threading.Thread.Sleep(3000);画面还是会假死3.不使用BackgroundWorker,自己来写线程来实现类似于BackgroundWorker的处理子线程给主线程成员赋值的迷惑C# code
// 代码中自己定义的按钮(非显示按钮)
private Button testBtn = new Button();
private void button1_Click(object sender, EventArgs e)
Thread thr = new Thread(ControlParent);
thr.Start();
private void ControlParent()
Thread.Sleep(3000);
// 给自己定义的按钮赋值没有问题
testBtn.Text = &eeee&;
// 给画面上显示的按钮赋值,InvalidOperationException错误(这里迷糊了,子线程不能直接给主线程赋值,那么主线程是什么?)
this.button1.Text = &asda&;// InvalidOperationException!!!!!!!!!!!
这里的两个按钮,同样是属于一个类,只不过一个显示在画面上,另一个只定义了没有显示,为什么一个赋值成功,另一个就是败了,求大哥大姐们来个破解之法,感激不尽。PS:窗体的this.BeginInvoke只能不阻塞后面代码的执行,不能解决画面假死以上描述够清楚了吧,希望坛子里的大牛们能够诲人不倦,相信不只是我迷糊,还会有不少人也在迷糊着,希望能够来人指教了,欢迎指教讨论,感激不尽------解决方案--------------------
this.progressBar1.Invoke(new System.Action(delegate()
double pro = (double)index / ((double)MaxId - (double)MinId) * 100;
this.lbprogressBar.Text = pro.ToString(&N2&) + &%&;
if (pro &= 100)
pro = 100;
this.progressBar1.Value = Convert.ToInt32(pro);
------解决方案--------------------C# code
this.BeginInvoke((MethodInvoker)delegate
this.button1.Text = &asda&;
------解决方案--------------------主线程就是UI线程啊。你在非UI线程上默认是不能更新UI线程上的东西的。你需要将更新这个委托交给UI线程自己去执行。你可以在ControlParent中这样写来更新BUTTON1this.Invoke(()=&{button1.Text=&asda&;});
------解决方案--------------------数据集.Fill(缓存数据表, 表名);/这里会是时钟控件无法执行/ 建立连接.Close();一般读数据库ACCESS会出现这种情况,慢的电脑会使主界面状态栏中显示时间停顿5-10秒不等,即使使用线程或一部也无法解决。图片一般使用异步也就可以了,慢的电脑也不显得慢。
------解决方案--------------------[code=C#][/code]using Susing System.Windows.Fusing System.Tnamespace WindowsFormsApplication1{
public partial class Form1 : Form
public Form1()
InitializeComponent();
private delegate void DeleWork();//委托
private Button testBtn = new Button();
private void button1_Click(object sender, EventArgs e)
Thread thread = new Thread(threadWork);
thread.IsBackground =
thread.Start();
private void threadWork()
DeleWork ThreadDeleWork = new DeleWork(FormDeleWork);
while (true)
Thread.Sleep(1000);
this.BeginInvoke(ThreadDeleWork);
private void FormDeleWork()
testBtn.Text = &eeee&;
this.button1.Text = &asda&;
textBox1.Text = testBtn.T
------解决方案--------------------一、子线程操作主线程的控件用委托就行;二、把延时的工作放到委托入口之外就不会假死了。希望对你有帮助。
------解决方案--------------------该UI做的就让UI去做,不该UI去做的就不要让UI去做。如果你让UI做的事情太多,比如加载1G的图片这种巨大的操作。那UI本身不做优化的话不卡死就怪了。
------解决方案--------------------LZ是担心这代码段会被不同你的线程访问时冲突吧
void SetTextBoxValue(object obj)&
this.textBox1.Text = obj.ToString();
}这样的话你可以加把锁如:object locker=new object();void SetTextBoxValue(object obj)&
lock(locker)
this.textBox1.Text = obj.ToString();
}这样就可以只有一个线程对SetTextBoxValue进行访问了,其他要访问的线程将会等待,直到SetTextBoxValue完成
------解决方案--------------------简便通用的方法C# code
public static void CrossThreadInvoke(Control ctrl, Action action)
if (ctrl.InvokeRequired)
ctrl.Invoke(action);
action.Invoke();
------解决方案--------------------tryC# code
public class Utils
public static void CrossThreadInvoke(Control ctrl, Action action)
if (ctrl.InvokeRequired)
ctrl.Invoke(action);
action.Invoke();
------解决方案--------------------C# code
Semaphore semaphore = new Semaphore(0, 1);
LoadMainForm(semaphore )
while (!semaphore.WaitOne(TimeSpan.FromMilliseconds(40), false))
Application.DoEvents();
private void LoadMainForm(Semaphore semaphore ){
ThreadPool.QueueUserWorkItem(delegate{
mainForm = new frmMain();
semaphore.Release();
catch (Exception ex){
semaphore.Release();
------解决方案--------------------探讨简便通用的方法C# code
public static void CrossThreadInvoke(Control ctrl, Action action)
if (ctrl.InvokeRequired)
ctrl.Invoke(action);
------解决方案--------------------
声明一个委托 delegate void aa();-------------------------------------------------
Thread.Sleep(3000);
// 给自己定义的按钮赋值没有问题
//testBtn.Text = &eeee&;
// 给画面上显示的按钮赋值,InvalidOperationException错误(这里迷糊了,子线程不能直接给主线程赋值,那么主线程是什么?)
//button1.Text = &asda&;
aa bb = delegate()
button1.Text = &asda&;// InvalidOperationException!!!!!!!!!!!
button1.Invoke(bb); &
这样不造成界面假死
------解决方案--------------------不知道为什么BackgroundWorker在事件中bw_DoWork中已经执行完后,为什么还要在事件bw_RunWorkerCompleted中添加sleep(100000)呢?bw_DoWork把要执行的全部执行完,之后通过参加传递给bw_RunWorkerCompleted,显示到界面上多好 啊?不明白你要做什么。我有使用线程实现类似BackgroundWorker的功能的代码。需要可以联系我。
------解决方案--------------------this.BeginInvoke和Delegate.BeginInvoke完全不是一个概念,你混淆了两者。要界面不卡,多线程后台操作,应该是用后者而不是前者。另外.NET4.5使用async是最佳方案,功能强大且编码快速,唯一的缺点是不支持XP。
------解决方案--------------------探讨你可以试一下这两种实现的效果的就会明白了,和直接Control.Invoke的区别就在于使用Control.Invoke时ui线程需要等待,算不上异步数据处理和ui更新不需要分开,放在一起就可以,一部分数据处理完马上就可以反映在ui上,而不是都处理完了在反映到ui
------解决方案--------------------这个以前遇到过,大数据量加载的假死是在给textbox赋值的时候,这个是瓶颈,不管你用什么方法加载数据,但是一次赋值给textbox的时候一定会假死,使用多少个线程都不行。可以使用分批加载,这样界面不会假死,但是用户仍然要等待,要做的再好一点,可以先加载一部分,等用户拉动滚动条的时候,再加载下一批数据。你可以感觉一下word或者ue的加载,都是分批加载的。再试试记事本是一次加载的(感觉上)。
------解决方案--------------------又纠结于数据的“一致性”,又纠结于硬要多线程去处理它,这往往是自相矛盾的。通常我丝毫没觉得有必要“用异步多线程的语法去模拟顺序阻塞处理”。不过如果你非常想看看异步线程是怎样阻塞自己的,可以参考帖子:http://topic.csdn.net/u//2f7f5cf3-f6e4-4d94-a352-24abdc6c8a2a.html?seed=&r=
------解决方案--------------------我们使用异步编程,是因为有多个足以异步处理的、无关的事情需要并行执行。因此异步编程的大忌就是“用异步多线程编程语法去模拟同步阻塞”,因为它的性能往往是灾难——比简单的顺序执行的性能还差劲。因此我对c#5版本的 await 关键字有些担心,我担心许多c#初学者被它“害了”,以为模拟同步阻塞是一种很随意的多线程设计习惯。尽管 await 本身实现时其实是回调的(而不是阻塞的),但是它没有给初学者展示一个科学而合理的异步多线程编程思路,反而是带到“阴沟”里去了。
------解决方案--------------------多线程的意义在于异步,不是分步!(本文来自互联网,不代表搜站(/)的观点和立场)本站所有内容来自互联网,若本站收录的信息无意侵犯了贵司版权,请给我们来信(),我们会及时处理和回复,谢谢编辑推荐最近更新}

我要回帖

更多关于 winform ui 的文章

更多推荐

版权声明:文章内容来源于网络,版权归原作者所有,如有侵权请点击这里与我们联系,我们将及时删除。

点击添加站长微信