[英]Correct Event handling in C#
這基本上是對上一個問題( 從c ++在c#中觸發事件並聲明LPCWSTR )的后續操作。 我已經根據收到的答案和評論修改了我的代碼,並解決了最初的問題,該問題將事件從gpio api傳遞到GpioSetupInterruptPin 。 我在api上沒有很多文檔,但是我想要達到的目的是:帶有白色標簽的表單; 按下開關后,標簽變為黃色。 我現在遇到的問題是事件似乎在創建事件后立即觸發(“執行”消息傳遞到調試對話框,並且標簽變為黃色),但是當我切換開關時它什么也沒做。 在最后一個問題中,有人告訴我使用WaitForSingleObject,但我不確定在哪里調用它,而這篇文章只會使我感到困惑。
public partial class Form1 : Form
{
// P/Invoke CreateEvent and WaitForSingleObject
private void GPIO_Open() //get handle for gpio
private void GPIO_Output() //output pin declaration
private void button1_Click(object sender, EventArgs e)
{
Interrupt_Setup();
}
private void Interrupt_Setup()
{
hGPIO = GPIOapi.GpioOpenHandle(); //returns a handle to the gpio
GIPO_ON = true;
Debug.WriteLine("Driver open \n" + hGPIO);
GPIO_Output(); //set output pins
GPIO_Interrupt(Trigger); //configure interrupt
}
private void GPIO_Interrupt(string trigger)
{
bool ok;
_Main();
//INTERRUPT DECALRATION
ok = GPIOapi.GpioSetupInterruptPin(hGPIO, port6, 4, GPIOapi.INT_TRIGGER_MODE.TRIGGER_MODE_EDGE,
GPIOapi.INT_TRIGGER_POLARITY.TRIGGER_POL_HIGH_RISING, trigger, true);
Thread waitThread=new Thread(WaitForTrigger);
waitThread.Start();
if (!ok)
Debug.WriteLine("NO interrupt");
else
Debug.WriteLine("Interrupt set for:" + port6 + "04" + " at " + hGPIO);
}
public static string Trigger = "InputProcessUpdateHandler";
public static IntPtr handle = CreateEvent(IntPtr.Zero, false, false, Trigger); //used P/Invoke
private static InputProcessor inputProcessor = null;
public Color[] color =
{
Color.Orchid, Color.DarkOrchid, Color.GreenYellow, Color.CornflowerBlue, Color.SteelBlue,Color.Crimson
};
public int i = 0;
public void WaitForTrigger()
{
while(true)
{try
{
if (WaitForSingleObject(handle, 0xFFFFFFFF) == false)
{
BeginInvoke(((System.Action)(() =>label2.BackColor = color[i])));
i++;
if (i > 4)
i = 0;
}
Thread.Sleep(300);
}
catch (Exception e)
{ Debug.WriteLine("exception: " + e); }}
}
}
private void _Main()
{
inputProcessor = new InputProcessor();
ShowToggle showToggle = new ShowToggle(inputProcessor);
inputProcessor.Process(label1);
}
public class ShowToggle
{
private InputProcessor _inputProcessor = null;
public ShowToggle(InputProcessor inputProcessor)
{
_inputProcessor = inputProcessor;
_inputProcessor.updateHandledBy += InputProcessUpdateHandler;
}
private void InputProcessUpdateHandler(Label label)
{
label.BackColor = Color.Yellow;
Debug.Write("execute");
}
}
public class InputProcessor
{
public delegate void InputProcessUpdateHandler(Label label);
public event InputProcessUpdateHandler updateHandledBy = null;
public void Process(Label label)
{
if (updateHandledBy != null)
updateHandledBy(label);
}
}
如果有人可以幫助我,我將非常感激。
***我讓它工作了,但看起來一團糟。 有人可以幫我弄清楚嗎?
您的代碼確實讓我感到困惑。 我認為您想要的是這樣的東西。 請記住,我在SO文本編輯器中輸入了此內容,因此不要指望它可以編譯並可以正常工作-這只是一個指南。 認為它比偽代碼高出一步。
public class DeviceInterrupt
{
IntPtr m_gpio;
string m_eventName;
public event EventHandler OnInterrupt;
public DeviceInterrupt(int port)
{
// get a driver handle
m_gpio = GPIO_Open();
// generate some unique event name
m_eventName = "GPIO_evt_" + port;
// wire up the interrupt
GpioSetupInterruptPin(m_gpio, port, m_eventName, ...);
// start a listener
new Thread(EventListenerProc)
{
IsBackground = true,
Name = "gpio listener"
}
.Start();
}
public void Dispose()
{
// TODO: release the handle
}
private void EventListenerProc()
{
// create the event with the name we sent to the driver
var wh = new WaitHandle(false, m_eventName);
while (true)
{
// wait for it to get set by the driver
if (wh.WaitOne(1000))
{
// we have an interrupt
OnInterrupt.Fire(this, EventArgs.Empty);
}
}
}
}
用法將是這樣的:
var intr = new DeviceInterrupt(4);
intr.OnInterrupt += MyHandler;
....
void MyHandler(object sender, EventArgs a)
{
Debug.WriteLine("Interrupt occurred!");
}
注意
Compact Framework不支持實際的命名系統事件,因此我在我的代碼中使用的命名WaitHandle
不是 CF提供的WaitHandle
。 相反,我使用的是Smart Device Framework中的那個。 您也可以自己P /調用CreateEvent
和WaitForSingleObject
。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.