我刚写了一个简单的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。
请告知。
答案 0 :(得分:0)
由于设备在其驱动程序中不支持回调,因此您可以通过在后台线程中轮询设备,使驱动程序的API从同步调用调整为回调。
首先,创建一个类,轮询设备以查找您有兴趣响应的物理事件。然后,在您的GUI代码中,将轮询工作放在后台并响应主线程中的回调。
我不熟悉ADLink驱动程序,因此我将总结一种设计方法并绘制一些不是线程安全的伪代码。这是一种使用Tasks的天真方法,但您也可以将其更新为使用延续或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;
}
}
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();
}