由于设备在其驱动程序中不支持回调,因此您可以通过在后台线程中轮询设备来调整驱动程序的 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();
}