我目前正在编写一个C#应用程序,它将接受来自多个USB连接输入设备的输入。使用the Raw Input library,我能够识别输入设备,然后根据输入设备完成操作。
示例:设备A输入是作为一系列击键接收的,构建了一个字符串,使用'内置的'来查询数据库。字符串作为参数,打印机A打印结果。
我遇到的问题是多个设备同时输入值时的延迟。设备A输入与设备B同时接收;打印机A立即打印,但打印机B在打印时遇到一些延迟。延迟时间不超过一秒,但对于此项目的预期目的而言,这是一秒钟。我正在使用条形码扫描仪所以我会说由于缺乏更好的定量测量,整个字符串的输入是闪电。
我不认为我的问题需要代表我的任何代码,但如果需要帮助回答问题,请告诉我,我可以提供一个代码段。我只是在寻找一个示例或策略来使用多线程输入到输出,如果这是有道理的。
感谢任何帮助。
编辑(添加当前代码):
private readonly RawInput _rawinput;
const bool CaptureOnlyInForeground = true;
public InputForm()
{
InitializeComponent();
_rawinput = new RawInput(Handle, CaptureOnlyInForeground);
}
string Scanner1ID;
string Scanner2ID;
string Printer1IP;
string Printer2IP;
int NumberIdentifier;
string ScannedItem;
string ScannedKey;
PLabel NewLabel = New PLabel();
//Various methods are used to identify each scanner and printer, print commands are sent via the TcpClient class in conjunction with a StreamWriter.
void StartScanning(object sender, EventArgs e)
{
AppDomain.CurrentDomain.UnhandledException += CurrentDomain_UnhandledException;
_rawinput.AddMessageFilter();
Win32.DeviceAudit();
_rawinput.KeyPressed += OnItemScanned;
}
private void OnItemScanned(object sender, RawInputEventArg e)
{
ScannedKey = e.KeyPressEvent.VKeyName.Replace("D", "");
if (int.TryParse(ScannedKey, out NumberIdentifier)
{
ScannedItem += ScannedKey;
if (e.KeyPressEvent.VKey == 13 || ScannedItem.Length == 10)
{
InOutList.Items.Add(ScannedItem); //Adds to list in form
if (e.KeyPressEvent.DeviceHandle.ToString() == Scanner1ID)
{
NewLabel.querySQL(ScannedItem);
Printer1Writer.Write(NewLabel.Results);
Printer1Writer.Flush();
}
else if (e.KeyPressEvent.DeviceHandle.ToString() == Scanner2ID)
{
NewLabel.pingSQL(ScannedHWB);
if (Client2Printer2.Connected)
{
NewLabel.querySQL(ScannedItem);
Printer2Writer.Write(NewLabel.Results);
Printer2Writer.Flush();
}
}
ScannedItem = "";
}
}
}
我可能已经遗漏了一些东西,但希望这已经足够了。
答案 0 :(得分:2)
根据你链接的文章
每个窗口的句柄与上一节中描述的已注册设备相关联,因此必须检查它收到的消息,并在检测到WM_INPUT时执行适当的操作。
Windows消息处理是一种协作式多任务处理。在当前的消息从处理返回之前,无法从消息队列中处理新消息。
如果您的代码通过在数据库中执行任何操作来响应WM_INPUT,则 没有其他事件可以处理,直到完成为止。
您可以使用生产者/消费者模式解决此问题。让处理WM_INPUT的代码将处理所需的信息放入诸如BlockingCollection之类的结构中,并从BlockingCollection中读取一个单独的线程并完成工作。
根据您的需要,每个原始输入设备可能只有一个BlockingCollection,或者只有一个。如果是后者,放入BlockingCollection的部分信息可能是生成输入的原始设备的标识符。