挑战:
我的表单包含14个标签和一个以100毫秒的间隔连续运行的计时器。在计时器内有代码,它与文件系统连接并检查是否存在某个文件。根据此文件的存在,简单的真或假,标签的背景颜色从灰色变为红色,然后在不再满足条件时变回灰色。
到目前为止一切正常。我可以编程,没有问题,它可以工作。
现在,在这个表单上还有几个按钮,我可能随时需要点击它们。但是,存在一个滞后现象,使用户体验看起来像表格被占用。我猜这是因为计时器必须更新UI,因此无法完全“集中”我的点击请求。我来自IT支持背景,我刚刚开始掌握OOP和C#.NET,所以我很开心:)我正在寻找一个简单的例子,可以帮助我掌握线程/独立执行的基础知识或者其他什么术语可能是。我很欣赏那里有很多例子,但你们其中一个可爱的人可以在我申请的背景下建议我可能需要做什么吗?
namespace WindowsFormsApplication1
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
private void Form1_Load(object sender, EventArgs e)
{
timer1.Start();
}
private void timer1_Tick(object sender, EventArgs e)
{
if (System.IO.File.Exists("C:\file.txt") == true)
{
label1.BackColor = System.Drawing.Color.Red;
//label2.BackColour..
//label3.BackColour..
//..
}
if (System.IO.File.Exists("C:\file.txt") == false)
{
label1.BackColor = System.Drawing.Color.Gray;
//label2.BackColour..
//label3.BackColour..
//..
}
}
private void button1_Click(object sender, EventArgs e)
{
//Do something
}
}
}
答案 0 :(得分:2)
使用FileSystemWatcher而不是轮询定时器上的文件。
答案 1 :(得分:0)
David Nelson建议的FileSystemWatcher是一个更好的选择,这是一种快速而且非常肮脏的方式:
public partial class Form1 : Form
{
private System.Threading.Timer timer1;
public Form1()
{
InitializeComponent();
this.timer1 = new System.Threading.Timer(state => {
var fileExists = System.IO.File.Exists(@"C:\file.txt");
this.BeginInvoke(new Action(() => {
if (fileExists) {
label1.BackColor = System.Drawing.Color.Red;
//label2.BackColour..
//label3.BackColour..
//..
}
else {
label1.BackColor = System.Drawing.Color.Gray;
//label2.BackColour..
//label3.BackColour..
//..
}
}));
}, null, 0, 100);
}
private void button1_Click(object sender, EventArgs e)
{
}
}
答案 2 :(得分:0)
假设延迟的根源是File.Exists
调用,而不是多个BackColor
分配,则可以使用Task.Run
将昂贵的调用卸载到线程池线程,并且然后await
获得结果:
private async void Timer1_Tick(object sender, EventArgs e)
{
var fileExists = await Task.Run(() => File.Exists("C:\file.txt"));
Color color = fileExists ? Color.Red : Color.Gray;
label1.BackColor = color;
label2.BackColor = color;
label3.BackColor = color;
//...
}