0

我刚刚编写了一个简单的 C#,以便在任何数字输入变高时从 PCI-7250(数据采集卡)获取事件回调。这是我的代码:

public delegate void ReadDelegate(uint value)
public void Form1_Load(object sender, EventArgs e)
 { 
    m_dev = DASK.Register_Card(DASK.PCI_7250,0);

    ReadDelegate ReadNow = new ReadDelegate(FunctionToCall) 
    DASK.DI_EventCallBack((ushort)m_dev,1,(short)DASK.DBEvent,ReadNow) 
} 
private void FunctionToCall(uint int_value) 
{
 MessageBox.Show(int_value) 
}

运行时,它只是在运行时不断抛出一些随机数,然后最终崩溃。我相信它与 EventType (DASK.DBEvent) 有关。我浏览了手册,但没有提及更多关于 DASK.DBEvent .

请指教。

4

1 回答 1

0

由于设备在其驱动程序中不支持回调,因此您可以通过在后台线程中轮询设备来调整驱动程序的 API 从同步调用到回调。

首先,创建一个轮询设备以查找您有兴趣响应的物理事件的类。然后,在您的 GUI 代码中,将轮询工作置于后台,并在主线程中响应回调。

我对 ADLink 驱动程序不熟悉,所以我将总结一种设计方法并草拟一些非线程安全的伪代码。这是使用Tasks的一种幼稚方法,但您也可以将其更新为使用 continuations 或async/await。或者,如果您需要多个响应者,请让回调引发您的其他类可以订阅的事件。

投票类

public class EdgeDetector
{
  public delegate void OnRisingEdgeDetected(uint currentValue, uint linesThatAsserted);
  private bool m_shouldPoll;

  private void PollForRisingEdge(PCI_7250 device, OnRisingEdgeDetected onRisingEdgeDetected)
  {
    while (m_shouldPoll)
    {
      // Optional: sleep to avoid consuming CPU

      uint newPortValue = device.ReadAllDigitalLines();
      uint changedLines = m_currentPortValue ^ newPortValue;
      uint risingEdges = newPortValue & changedLines;
      m_currentPortValue = newPortValue;

      if (risingEdges != 0)
      {
        onRisingEdgeDetected(currentValue: newPortValue,
                             linesThatAsserted: risingEdges);
      }
  }

  public void Start(PCI_7250 device, OnRisingEdgeDetected onRisingEdgeDetected)
  {
      m_shouldPoll = true;
      PollForRisingEdge(device, onRisingEdgeDetected);
  }

  public void Stop()
  {
      m_shouldPoll = false;
  }
}

WinForm 类

private void Initialize()
{
  m_dev = DASK.Register_Card(DASK.PCI_7250, 0);
  m_mainThreadScheduler = TaskScheduler.FromCurrentSynchronizationContext();
}

private void StartEdgeDetection()
{
  m_edgeDetectionTask = Task.Factory.StartNew( () =>
    {
      m_edgeDetector.Start(device: m_dev, onRisingEdgeDetected: RescheduleOnMainThread);
    });
}

private RescheduleOnMainThread(uint currentValue, uint linesThatAsserted)
{
  m_onEdgeDetectionTask = Task.Factory.StartNew(
    action: () =>
      {
        MessageBox.Show(currentValue);
      },
    cancellationToken: null,
    creationOptions: TaskCreationOptions.None,
    scheduler: m_mainThreadScheduler);
}

private void CleanUp()
{
  m_edgeDetector.Stop();
  m_edgeDetectionTask.Wait();
  m_onEdgeDetectionTask.Wait();
}

public void Form1_Load(object sender, EventArgs e)
{
  Initialize();
  StartEdgeDetection();
}

public void Form1_Closed(object sender, EventArgs e)
{
  CleanUp();
}
于 2014-12-27T19:15:18.897 回答