我有一个校队项目,我必须在后台使用RFID阅读器来跟踪员工的时钟输入/输出。前台winform GUI处理日常交易,例如订单,报价等。因此,我需要能够不间断地使用该程序,同时跟踪员工的来往。我已经调查了背景工作者,某种新的踩踏和输入抓取。但我似乎无法找到任何可行的东西。 RFID阅读器充当键盘,我可以得到它的名字。使用Raw Input
为了澄清,用户必须能够不间断地使用该程序(多种形式),而RFID读取器的任何输入必须记录在后台列表中。
我是背景工作者的新手,多线程和输入抓取所以我将非常感谢一些详细的帮助。如果您需要我的更多细节,请询问。
答案 0 :(得分:1)
我在这里使用RFID阅读器,NordicID Sampo附带一个API,用于激活读取数据的线程。您可以通过创建一个Task来构建,该Task从该线程添加的缓冲区中读取数据。然后,您可以将该数据传递给表单或通过电子邮件发送或其他任何内容。
你的扫描仪可能也有同样的机制。
示例: StartStreaming是设备API的包装器,它会触发读取设备数据的线程。
class RFIDReader : IDisposable
{
public void StartStreaming()
{
if (RFID_ConnectSerialPort(mAPIHandle, 4, 115200) == 0 || RFID_ConnectAutoUSB(mAPIHandle) == 0)
{
RFID_StartInventoryStreaming(
(value, antenna) => {
mAntennas[antenna].Add(value);
});
}
}
/////// MORE FUNCTIONS
}
客户端代码,它会激活自己的任务并定期检查数据:
static void Main(string[] args)
{
Action a = new Action(() =>
{
using (RFIDReader scanner = new RFIDReader())
{
scanner.StartStreaming();
while (true)
{
foreach (string s in scanner.GetData(0))
{
WriteLine($"antenna0: {s}");
}
Thread.Sleep(1000);
}
}
});
Task t = Task.Factory.StartNew(a);
t.Wait();
}
答案 1 :(得分:1)
如果您使用LibUsbDotNet 你可以对DataReceivedEvent做出反应。因此,在轮询新数据时,您可以避免阻塞。如果您选择了轮询aproach @Servé已经向您展示了如何将其发送到另一个任务以避免阻塞主线程。
所以这是使用DataReceivedEvent建议的解决方案。
初始化USB设备:
IUsbDevice wholeUsbDevice = PhysicalLibUSBDevice as IUsbDevice;
if (!ReferenceEquals(wholeUsbDevice, null))
{
// This is a "whole" USB device. Before it can be used,
// the desired configuration and interface must be selected.
// Select config #1
wholeUsbDevice.SetConfiguration(1);
// Claim interface #0.
wholeUsbDevice.ClaimInterface(0);
}
// Create the reader and writer streams
_libUsbReader = PhysicalLibUSBDevice.OpenEndpointReader(LibUsbDotNet.Main.ReadEndpointID.Ep01);
_libUsbWriter = PhysicalLibUSBDevice.OpenEndpointWriter(LibUsbDotNet.Main.WriteEndpointID.Ep02);
_libUsbReader.DataReceived += OnDataReceived;
_libUsbReader.DataReceivedEnabled = true;
_libUsbReader.ReadThreadPriority = System.Threading.ThreadPriority.Highest;
_libUsbReader.ReadBufferSize = 32;
定义Eventhandler:
private void OnDataReceived(object sender, EndpointDataEventArgs e)
{
//Use the Buffer and Count Properties of the EventArgs to get the received data
Console.WriteLine("Data received");
}
答案 2 :(得分:0)
多线程并不容易。 BackgroundWorker在GUI上稍微容易一些,但仍然很难从后台任务中访问GUI。为什么不先试用Task/Await
?这避免了多线程,仍然可以运行两个任务。