我有一个表单Form1,带有一个按钮和文本框。 当我点击按钮时,我应该从USB设备获取一些数据。 出于某种原因,它只能正常工作2%(我在100次点击中得到了2个正确答案)。 这是Form1的代码:
namespace Test_onForm1
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
private void button1_Click(object sender, EventArgs e)
{
Lib1.FindHID.TransferInputAndOutputReports(0xC0); //request specific data from USB device
}
}
}
处理USB通信的代码在DLL Lib1中(以下代码的片段):
namespace Lib1
{
public static class FindHID
{
private static void TransferInputAndOutputReports(UInt16 repType)
{
//some code here sending request to USB device... and then read what came from USB
ReadInput();
//some code here
}
// Read an Input report.
private static void ReadInput()
{
Byte[] inputReportBuffer = null;
inputReportBuffer = new Byte[MyHid.Capabilities.InputReportByteLength];
IAsyncResult ar = null;
if (fileStreamDeviceData.CanRead)
{
// RUNS UP TO THIS POINT and then Form1 freezes most of the time
fileStreamDeviceData.BeginRead(inputReportBuffer, 0, inputReportBuffer.Length, new AsyncCallback(GetInputReportData), inputReportBuffer);
}
}
private static void GetInputReportData(IAsyncResult ar)
{
// RARELY GETS HERE
Byte[] inputReportBuffer = null;
inputReportBuffer = (byte[])ar.AsyncState;
fileStremDeviceData.EndRead(ar); //waits for read to complete
// then code to update Form1
}
}
}
}
当它不起作用时,它会在fileStreamDeviceData.BeginRead周围停止,然后Form1冻结。
为了测试,我创建了一个全新的项目,而不是使用DLL,我将所有DLL代码复制到Form1。 此选项在100%的时间内完美运行。 所以我的问题是为什么它不适用于DLL?
更新:当我幸运并开始工作时,它会无限期地工作,直到我关闭申请。然后,我必须继续努力让它再次运作。 如何解决这个问题?
答案 0 :(得分:0)
问题很可能是EndRead
中的代码正在尝试更新表单,但它不在UI线程上。您必须通过执行Form.Invoke
或以某种方式通知表单数据已准备好以便UI线程可以执行更新来与UI线程同步。
答案 1 :(得分:0)
解决!
在Microsoft网站上找到: “流上的BeginRead的默认实现同步调用Read方法,这意味着Read可能会阻塞某些流。”
我在Visual Studio 2010上使用.NET Framework 4.0。
决定更新到具有Stream.ReadAsync
方法的.NET Framework 4.5。但是,我无法在Visual Studio 2010上实现Stream.ReadAsync
(不知道原因,可能需要更新到2012年?)。
因此,使用更新的Framework 4.5,我尝试了我的代码,它可以随时工作。