首页 / C# / c#Parallel.For和UI更新?
c#Parallel.For和UI更新?
内容导读
互联网集市收集整理的这篇技术教程文章主要介绍了c#Parallel.For和UI更新?,小编现在分享给大家,供广大互联网技能从业者学习和参考。文章包含2434字,纯文字阅读大概需要4分钟。
内容图文
![c#Parallel.For和UI更新?](/upload/InfoBanner/zyjiaocheng/821/fe5120de172c42a88e8c22f267b34db4.jpg)
我正在尝试实现一个Parallel.ForEach循环来替换旧的foreach循环,但我无法更新我的UI(我有一个计数器显示类似’x / y文件已处理’).我已经制作了一个Parallel Forloop示例来说明我的问题(标签没有更新).
using System;
using System.Windows.Forms;
using System.Threading.Tasks;
using System.Threading;
namespace FormThreadTest
{
public partial class Form1 : Form
{
private SynchronizationContext m_sync;
private System.Timers.Timer m_timer;
private int m_count;
public Form1()
{
InitializeComponent();
m_sync = SynchronizationContext.Current;
m_count = 0;
m_timer = new System.Timers.Timer();
m_timer.Interval = 1000;
m_timer.AutoReset = true;
m_timer.Elapsed += new System.Timers.ElapsedEventHandler(m_timer_Elapsed);
m_timer.Start();
}
private void m_timer_Elapsed(object sender, System.Timers.ElapsedEventArgs e)
{
Task.Factory.StartNew(() =>
{
m_sync.Post((o) =>
{
label1.Text = m_count.ToString();
Application.DoEvents();
}, null);
});
}
private void button1_Click(object sender, EventArgs e)
{
Task.Factory.StartNew(() =>
{
Parallel.For(0, 25000000, delegate(int i)
{
m_count = i;
});
});
}
}
}
如果我更改按钮单击事件方法,并添加一个Thread.Sleep(),它似乎给了UI更新线程完成其工作的时间:
private void button1_Click(object sender, EventArgs e)
{
Task.Factory.StartNew(() =>
{
Parallel.For(0, 25000000, delegate(int i)
{
m_count = i;
Thread.Sleep(10);
});
});
}
有没有办法避免睡眠,或者我需要在那里睡觉吗?看起来我的ui不会更新标签,除非我这样做?我觉得很奇怪,因为我可以移动应用程序窗口(它没有锁定) – 所以为什么标签不会更新,我怎么能改变我的代码以更好地支持Parallel.For(每个)和UI更新?
我一直在寻找解决方案,但我似乎找不到任何东西(或者我可能正在寻找错误的东西?).
问候
西蒙
解决方法:
我的猜测是,数到2500万(并行!)只需不到一秒钟……因此在计数完成之前你的计时器不会被触发.如果你添加Thread.Sleep,整个过程会运行得慢得多,以便你可以看到更新.
另一方面,您的计时器事件处理程序看起来很乱.您生成一个线程以向您的UI发布消息,当您最终在UI线程上时,您调用Application.DoEvents …为什么?您应该能够删除任务创建和DoEvents调用.
编辑:我测试了您发布的程序,并看到标签更新两次.我的电脑需要超过一秒才能达到25米.我将这个数字增加到了10亿,并且标签更新了多次.
Edit2:您可以将计时器处理程序减少到
private void m_timer_Elapsed(object sender, System.Timers.ElapsedEventArgs e)
{
m_sync.Post((o) =>
{
label1.Text = m_count.ToString();
}, null);
}
不幸的是,显示的数字不是当前处理的项目数,而是在引发计时器事件时恰好处理的项目的索引.你必须自己实施计数.这可以通过使用来完成
Interlocked.Add(ref m_count, 1);
内容总结
以上是互联网集市为您收集整理的c#Parallel.For和UI更新?全部内容,希望文章能够帮你解决c#Parallel.For和UI更新?所遇到的程序开发问题。 如果觉得互联网集市技术教程内容还不错,欢迎将互联网集市网站推荐给程序员好友。
内容备注
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 gblab@vip.qq.com 举报,一经查实,本站将立刻删除。
内容手机端
扫描二维码推送至手机访问。