问题描述
当前,我有一个项目,其中包含一些WinForms绑定,以允许不仅使用鼠标而且还可以通过外部硬件设备来操作界面。
外部设备通过DLL进行接口,该DLL允许订阅从单独线程发送的硬件按钮按下事件。
这是我为按钮制作的类的样子(细节省略):
public class PanelBoundButton : Button,IPanelBoundControl
{
/// <summary>
/// Gets or sets what hardware button the control is bound to.
/// </summary>
[Description("Panel button to bind"),Category("Hardware Interface")]
public HardwareButtonFlags Binding
{
get;
set;
}
// For debouncing
private DateTime pressTime = DateTime.MinValue;
private const int DEBOUNCE_MS = 100;
public void Bind()
{
if (LicenseManager.UsageMode == LicenseUsageMode.Designtime) return;
ButtonReader.ButtonsChanged += new EventHandler<HardwareButtonEvent>(HardwareHandleButtonChange);
}
public void Unbind()
{
if (LicenseManager.UsageMode == LicenseUsageMode.Designtime) return;
ButtonReader.ButtonsChanged -= HardwareHandleButtonChange;
}
// External hardware button event handler
void HardwareHandleButtonChange(object sender,HardwareButtonEvent e)
{
if (this.Binding != 0 && e.Released.HasFlag(this.Binding) && this.Enabled)
{
if(DateTime.Now.Subtract(pressTime).TotalMilliseconds < DEBOUNCE_MS)
{
Logger.Log("Button event seems like noise,ignoring for debouncing");
return;
}
pressTime = DateTime.Now;
Action clk = delegate()
{
this.PerformClick();
};
if (this.InvokeRequired)
this.Invoke(clk);
else clk();
}
}
}
但是,有时在操作按钮时,尤其是关闭窗体的按钮时,用户使用以下堆栈跟踪会崩溃。最初,我认为可能是因为两次按下按钮被识别,因此上面代码中的反跳部分仍然没有帮助(并且也从未记录过反跳线)。
Cannot access a disposed object.
Object name: 'AppOperationSelectorTabPages'.
Happened in object: System.Windows.Forms
Happened in method: System.Object MarshaledInvoke(System.Windows.Forms.Control,System.Delegate,System.Object[],Boolean)
at System.Windows.Forms.Control.MarshaledInvoke(Control caller,Delegate method,Object[] args,Boolean synchronous)
at System.Windows.Forms.Control.Invoke(Delegate method,Object[] args)
at projectname.GUI.PanelBoundButton.HardwareHandleButtonChange(Object sender,HardwareButtonEvent e)
at System.EventHandler`1.Invoke(Object sender,TEventArgs e)
at projectIoLib.FrontPanel.ButtonReader.OnButtonEvent(Object sender,HardwareButtonEvent e)
at projectIoLib.FrontPanel.ButtonEventEmitter._ButtonCheckingThread()
at System.Threading.ExecutionContext.RunInternal(ExecutionContext executionContext,ContextCallback callback,Object state,Boolean preserveSyncCtx)
at System.Threading.ExecutionContext.Run(ExecutionContext executionContext,Object state)
at System.Threading.ThreadHelper.ThreadStart()
但是,从这个堆栈跟踪中我无法真正确定访问时放置了哪个对象?是我的按钮吗?还是TabPages对象?
此外,当前取消绑定的按钮在关闭时由表单处理。但是我的猜测是,这种情况发生得足够晚,以至于发生崩溃。
我是否在我的按钮类中缺少某种方法的替代(例如Dispose
),以便在处理致命事件之前取消订阅硬件事件?
解决方法
暂无找到可以解决该程序问题的有效方法,小编努力寻找整理中!
如果你已经找到好的解决方法,欢迎将解决方案带上本链接一起发送给小编。
小编邮箱:dio#foxmail.com (将#修改为@)