C# 执行耗时操作导致界面卡顿假死的问题

SummerLee12 2017-08-29 11:00:58
各位好,程序执行一个耗时操作的时候(32768长度的16进制数字转换为二进制string,还需要将一些数据在控件上显示),开始转换了界面就假死,大概5-10s等转换的代码执行完毕了才能操作界面,查了资料尝试了beginInvoke和多线程,但UI界面依然会这样,求助,谢谢了!
...全文
3372 18 打赏 收藏 转发到动态 举报
写回复
用AI写文章
18 条回复
切换为时间正序
请发表友善的回复…
发表回复
正怒月神 2017-08-30
  • 打赏
  • 举报
回复
你的begininvlke回调的方法是更新ui线程嘛?
白衣如花 2017-08-30
  • 打赏
  • 举报
回复
byte[] ba = new byte[32768];
for (int i = 0; i < 32768; i++)
    ba[i] = (byte)(i % 128);
Stopwatch sw = new Stopwatch();
sw.Start();
StringBuilder sb = new StringBuilder(32768 * 2);
for (int i = 0; i < 32768; i++)
    sb.Append(ba[i].ToString("X2"));
string result = sb.ToString();
Console.WriteLine(sw.ElapsedMilliseconds);

sw.Restart();
result = string.Empty;
for (int i = 0; i < 32768; i++)
    result += ba[i].ToString("X2");
Console.WriteLine(sw.ElapsedMilliseconds);

sw.Restart();
sb = new StringBuilder();
for (int i = 0; i < 32768; i++)
    sb.Append(ba[i].ToString("X2"));
result = sb.ToString();
Console.WriteLine(sw.ElapsedMilliseconds);
分别耗时4 600 4 毫秒 为什么你的那么耗时间?
易2017 2017-08-30
  • 打赏
  • 举报
回复
引用 12 楼 kangmao2809 的回复:
[quote=引用 11 楼 xdashewan 的回复:] [quote=引用 8 楼 kangmao2809 的回复:] 还有跨线程操作控件,在多线程的方法里有Invoke控件
你需要操作多少控件?[/quote] 更新四个textBox的值,读取一个richTextBox的值 另外主楼表述有误,应该是32768Byte,我在控制台试了一下,转换时间大概是4s,窗体8s,所以基本上堵塞的时间主要还是在转换。 多线程方法里去掉委托操作控件的语句之后,不会再卡死界面 但是几个tabpage页切换会有卡顿[/quote] 检查一下你的事件是否重复注册,tabpage切换时是否触发来了某些延时操作如数据库查询,跨线程操作UI你可以把下面这句写入窗体初始化中
 CheckForIllegalCrossThreadCalls = false;
SummerLee12 2017-08-30
  • 打赏
  • 举报
回复
引用 11 楼 xdashewan 的回复:
[quote=引用 8 楼 kangmao2809 的回复:] 还有跨线程操作控件,在多线程的方法里有Invoke控件
你需要操作多少控件?[/quote] 更新四个textBox的值,读取一个richTextBox的值 另外主楼表述有误,应该是32768Byte,我在控制台试了一下,转换时间大概是4s,窗体8s,所以基本上堵塞的时间主要还是在转换。 多线程方法里去掉委托操作控件的语句之后,不会再卡死界面 但是几个tabpage页切换会有卡顿
SummerLee12 2017-08-30
  • 打赏
  • 举报
回复
引用 13 楼 qq_38588710 的回复:
[quote=引用 12 楼 kangmao2809 的回复:] [quote=引用 11 楼 xdashewan 的回复:] [quote=引用 8 楼 kangmao2809 的回复:] 还有跨线程操作控件,在多线程的方法里有Invoke控件
你需要操作多少控件?[/quote] 更新四个textBox的值,读取一个richTextBox的值 另外主楼表述有误,应该是32768Byte,我在控制台试了一下,转换时间大概是4s,窗体8s,所以基本上堵塞的时间主要还是在转换。 多线程方法里去掉委托操作控件的语句之后,不会再卡死界面 但是几个tabpage页切换会有卡顿[/quote] 检查一下你的事件是否重复注册,tabpage切换时是否触发来了某些延时操作如数据库查询,跨线程操作UI你可以把下面这句写入窗体初始化中
 CheckForIllegalCrossThreadCalls = false;
[/quote] 好的,谢谢!
SummerLee12 2017-08-30
  • 打赏
  • 举报
回复
引用 15 楼 hanjun0612 的回复:
你的begininvlke回调的方法是更新ui线程嘛?
之前是需要的,现在已经改了
SummerLee12 2017-08-30
  • 打赏
  • 举报
回复
引用 14 楼 u012948520 的回复:
byte[] ba = new byte[32768];
for (int i = 0; i < 32768; i++)
    ba[i] = (byte)(i % 128);
Stopwatch sw = new Stopwatch();
sw.Start();
StringBuilder sb = new StringBuilder(32768 * 2);
for (int i = 0; i < 32768; i++)
    sb.Append(ba[i].ToString("X2"));
string result = sb.ToString();
Console.WriteLine(sw.ElapsedMilliseconds);

sw.Restart();
result = string.Empty;
for (int i = 0; i < 32768; i++)
    result += ba[i].ToString("X2");
Console.WriteLine(sw.ElapsedMilliseconds);

sw.Restart();
sb = new StringBuilder();
for (int i = 0; i < 32768; i++)
    sb.Append(ba[i].ToString("X2"));
result = sb.ToString();
Console.WriteLine(sw.ElapsedMilliseconds);
分别耗时4 600 4 毫秒 为什么你的那么耗时间?
那个转换函数应该是不够优化,这个会参考,感谢!
exception92 2017-08-29
  • 打赏
  • 举报
回复
用多线程执行是可以的,你要多尝试几次多线程的写法,注意不要“跨线程”来操作UI控件。
sx_lxh 2017-08-29
  • 打赏
  • 举报
回复
多线程 http://www.360doc.com/content/10/0831/15/2917290_50145639.shtml
易2017 2017-08-29
  • 打赏
  • 举报
回复
引用 楼主 kangmao2809 的回复:
各位好,程序执行一个耗时操作的时候(32768长度的16进制数字转换为二进制string,还需要将一些数据在控件上显示),开始转换了界面就假死,大概5-10s等转换的代码执行完毕了才能操作界面,查了资料尝试了beginInvoke和多线程,但UI界面依然会这样,求助,谢谢了!
你的代码转换在主线程执行的?
xdashewan 2017-08-29
  • 打赏
  • 举报
回复
才转16384个byte应该没那么慢吧,而且用了多线程还卡死,多线程使用方式有错误吗?上代码吧
xdashewan 2017-08-29
  • 打赏
  • 举报
回复
引用 8 楼 kangmao2809 的回复:
还有跨线程操作控件,在多线程的方法里有Invoke控件
你需要操作多少控件?
exception92 2017-08-29
  • 打赏
  • 举报
回复
引用 7 楼 kangmao2809 的回复:
[quote=引用 4 楼 duanzi_peng 的回复:] 用多线程执行是可以的,你要多尝试几次多线程的写法,注意不要“跨线程”来操作UI控件。
试了不跨线程操作UI控件,确实不会卡死了,但界面里tabPage切换的时候会有闪白屏或者刷新过程较慢的现象,这个是因为异步的原因吗? 另外如果我还是有操作控件的需求,是只能放在主线程了么? [/quote] 和异步没关系,异步是CLR对代码执行的控制,和你的UI呈现没关系。 还是有操作控件的需求,是只能放在主线程了么 -》并不一定,每个控件都有一个InvokeRequired属性,用来判定调用者是否来自其它线程,如果值为true,就通过执行控件的Invoke/beginInvoke 来操作控件。
SummerLee12 2017-08-29
  • 打赏
  • 举报
回复
引用 2 楼 qq_38588710 的回复:
[quote=引用 楼主 kangmao2809 的回复:] 各位好,程序执行一个耗时操作的时候(32768长度的16进制数字转换为二进制string,还需要将一些数据在控件上显示),开始转换了界面就假死,大概5-10s等转换的代码执行完毕了才能操作界面,查了资料尝试了beginInvoke和多线程,但UI界面依然会这样,求助,谢谢了!
你的代码转换在主线程执行的?[/quote] 是在thread的方法里执行的
SummerLee12 2017-08-29
  • 打赏
  • 举报
回复
引用 1 楼 xdashewan 的回复:
才转16384个byte应该没那么慢吧,而且用了多线程还卡死,多线程使用方式有错误吗?上代码吧
还有跨线程操作控件,在多线程的方法里有Invoke控件
SummerLee12 2017-08-29
  • 打赏
  • 举报
回复
引用 4 楼 duanzi_peng 的回复:
用多线程执行是可以的,你要多尝试几次多线程的写法,注意不要“跨线程”来操作UI控件。
试了不跨线程操作UI控件,确实不会卡死了,但界面里tabPage切换的时候会有闪白屏或者刷新过程较慢的现象,这个是因为异步的原因吗? 另外如果我还是有操作控件的需求,是只能放在主线程了么?
大鱼> 2017-08-29
  • 打赏
  • 举报
回复
多线程没用好,估计是开了多线程,但是又委托给UI线程进行处理了。
ilikeff8 2017-08-29
  • 打赏
  • 举报
回复
八成你线程里吧耗时操作也包括在调用主线程的执行块里,线程等于没用

110,567

社区成员

发帖
与我相关
我的任务
社区描述
.NET技术 C#
社区管理员
  • C#
  • Web++
  • by_封爱
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告

让您成为最强悍的C#开发者

试试用AI创作助手写篇文章吧