C# 从NFC标记读取器事件处理程序更新UI非常慢
我有一个ACR122U NFC阅读器,在那里我可以阅读MiFare超轻NFC标签。我为我的读者下载了一个框架。但是,当调用事件处理程序时,GUI的更新非常缓慢C# 从NFC标记读取器事件处理程序更新UI非常慢,c#,winforms,nfc,C#,Winforms,Nfc,我有一个ACR122U NFC阅读器,在那里我可以阅读MiFare超轻NFC标签。我为我的读者下载了一个框架。但是,当调用事件处理程序时,GUI的更新非常缓慢 private void StartMonitor() { //Function called when starting the Windows Forms Application IMonitorFactory monitorfactory = MonitorFactory.Instance;
private void StartMonitor()
{
//Function called when starting the Windows Forms Application
IMonitorFactory monitorfactory = MonitorFactory.Instance;
monitor = monitorfactory.Create(SCardScope.System);
monitor.Start(ReaderNames[0]);
monitor.StatusChanged += Monitor_StatusChanged;
}
private void Monitor_StatusChanged(object sender, StatusChangeEventArgs e)
{
strPassportNo = "";
strPassportNo = lPassportNumberNo.Text;
if (e.NewState.ToString().ToLower().Contains("empty".ToLower()) == true)
{
//Interface should be deleted all by once now as no NFC tag is on the reader.
UpdateInterface();
}
}
private void UpdateInterface()
{
if (InvokeRequired)
{
this.BeginInvoke(new Action(() =>
{
lPassportNumberNo.Text = "";
lPassengerName.Text = "";
lPax.Text = "";
lTableNo.Text = "";
lRoomNo.Text = "";
pbTables.Hide();
pbPasspic.Hide();
this.BackgroundImage = BackgroundWelcome;
}));
}
else
{
lPassportNumberNo.Text = "";
lPassengerName.Text = "";
lPax.Text = "";
lTableNo.Text = "";
lRoomNo.Text = "";
pbTables.Hide();
pbPasspic.Hide();
this.BackgroundImage = BackgroundWelcome;
}
}
我在线程编程和事件处理方面没有太多经验。也许我的问题的答案很简单
但是,它只更新UpdateInterface()方法中的“label by label”,一次更新一个。我可以看到每个标签都消失了。所以UI的更新非常慢
我猜这与后台的reader类调用的(硬件)事件有关
这个程序一般都在运行,只是速度很慢
private void StartMonitor()
{
//Function called when starting the Windows Forms Application
IMonitorFactory monitorfactory = MonitorFactory.Instance;
monitor = monitorfactory.Create(SCardScope.System);
monitor.Start(ReaderNames[0]);
monitor.StatusChanged += Monitor_StatusChanged;
}
private void Monitor_StatusChanged(object sender, StatusChangeEventArgs e)
{
strPassportNo = "";
strPassportNo = lPassportNumberNo.Text;
if (e.NewState.ToString().ToLower().Contains("empty".ToLower()) == true)
{
//Interface should be deleted all by once now as no NFC tag is on the reader.
UpdateInterface();
}
}
private void UpdateInterface()
{
if (InvokeRequired)
{
this.BeginInvoke(new Action(() =>
{
lPassportNumberNo.Text = "";
lPassengerName.Text = "";
lPax.Text = "";
lTableNo.Text = "";
lRoomNo.Text = "";
pbTables.Hide();
pbPasspic.Hide();
this.BackgroundImage = BackgroundWelcome;
}));
}
else
{
lPassportNumberNo.Text = "";
lPassengerName.Text = "";
lPax.Text = "";
lTableNo.Text = "";
lRoomNo.Text = "";
pbTables.Hide();
pbPasspic.Hide();
this.BackgroundImage = BackgroundWelcome;
}
}
预期的结果应该是UI的性能比实际快得多。或者至少包含数据的标签应该立即出现和消失 不确定这到底是什么:
this.BackgroundImage=backgroundelcome但是每次都分配这样的静态数据真的有必要吗
另外,我不认为更新事件的频率太高-屏幕上的信息应该是人类可读的,所以在读取整个标记之后,它肯定只需要对所有数据进行一次更新。如果每个标签都有许多读取事件,那么将它们全部存储到临时列表中,并在读取端更新表单(整个标签)。
当我说“标签”时,我指的是整个mifare卡内容。在我的情况下,UI更新只是为了清除标签(请参阅UpdateInterface()。然而,我发现了“错误”。每次刷新时都会加载“.jpg”文件作为背景图像。虽然它“只是”1280x1024,但对于前端来说,更新太多了
当我清除图像时,立即刷新
我现在的解决办法是:
this.BackgroundImage = ((System.Drawing.Image(resources.GetObject("$this.BackgroundImage")));
this.BackgroundImageLayout = System.Windows.Forms.ImageLayout.Zoom;
this.SetStyle(System.Windows.Forms.ControlStyles.OptimizedDoubleBuffer | System.Windows.Forms.ControlStyles.AllPaintingInWmPaint, true);
在Form1.Designer.cs中
然后用下面的类暂停并恢复布局(我在互联网上找到的)
我还将“.jpg”文件更改为“.bmp”文件。现在的界面是平滑和快速的
和开玩笑:
不确定这到底是什么:this.BackgroundImage=backgroundelcome;但每次都分配这样的静态数据真的有必要吗
不,我本可以找到更好的解决办法。然而,由于应用程序非常小,我只有四个背景图像,我发现更容易“硬编码”它
最后,标签(-reader)并不是真正的问题
为了更新UI,我使用了这个非常简单的功能:
private void UpdateInterface(PassportDatabaseReader.Passport _passport)
{
if (InvokeRequired)
{
this.BeginInvoke(new Action<PassportDatabaseReader.Passport>(UpdateInterface), new object[] { _passport });
return;
}
else
{
ControlHelper.SuspendDrawing(this);
new Thread(() => ChangeBackground(BackgroundPassport)).Start();
lPassportNumberNo.Text = _passport.PassportNo;
strPassportNo = _passport.PassportNo;
lPassengerName.Text = _passport.Name.Replace('$','\n');
lPax.Text = _passport.Pax;
lTableNo.Text = _passport.TableNo;
lRoomNo.Text = _passport.RoomNo;
pbTables.Hide();
try
{
pbPasspic.Load("..\\..\\Pics\\" + _passport.PassportNo + ".png");
pbPasspic.Show();
pbTables.ImageLocation = "..\\..\\Tischordnung_" + _passport.TableNo + ".png";
pbTables.Show();
}
catch (Exception)
{
throw;
}
ControlHelper.ResumeDrawing(this);
}
}
private void UpdateInterface(PassportDatabaseReader.Passport\u Passport)
{
如果(需要调用)
{
this.BeginInvoke(新操作(UpdateInterface),新对象[]{u passport});
返回;
}
其他的
{
ControlHelper.SuspendDrawing(此);
新线程(()=>ChangeBackground(BackgroundPassport)).Start();
lPassportNumberNo.Text=\u passport.PassportNo;
strPassportNo=\u passport.PassportNo;
lPassengerName.Text=_passport.Name.Replace(“$”,“\n”);
lPax.Text=_passport.Pax;
lTableNo.Text=\u passport.TableNo;
lRoomNo.Text=\u passport.RoomNo;
pbTables.Hide();
尝试
{
pbPasspic.Load(“..\\..\\Pics\\”+_passport.PassportNo+.png”);
pbPasspic.Show();
pbTables.ImageLocation=“..\\\..\\Tischordnung_”+\u passport.TableNo+”.png”;
pbTables.Show();
}
捕获(例外)
{
投掷;
}
ControlHelper.ResumeDrawing(本);
}
}
该应用程序是一个“婚礼通行证”阅读器,它在屏幕上显示姓名、宾客房间号、桌子号以及“通行证”图片。听起来像是要批量处理来自monitor.StatusChanged事件的NFC更新。我看不到你在哪里更新UI。您需要使用beginupdate方法在UI线程上执行这些更新。