C# 是否可以使用封闭形式';有什么事要办?
我从FrmDelivery调用一个“Find”表单。在尝试将条形码扫描到编辑框时,“查找”表单崩溃(在应用程序的其他地方,例如在FrmDelivery中,相同的代码也可以正常工作) 日志文件显示FrmDelivery是遇到异常的表单:C# 是否可以使用封闭形式';有什么事要办?,c#,forms,barcode,barcode-scanner,scanning,C#,Forms,Barcode,Barcode Scanner,Scanning,我从FrmDelivery调用一个“Find”表单。在尝试将条形码扫描到编辑框时,“查找”表单崩溃(在应用程序的其他地方,例如在FrmDelivery中,相同的代码也可以正常工作) 日志文件显示FrmDelivery是遇到异常的表单: Message: Reached frmDelivery.StartRead Date: 2/19/2015 7:39:39 PM Message: From FrmDelivery.StartRead(): The scanner not enabled, C
Message: Reached frmDelivery.StartRead
Date: 2/19/2015 7:39:39 PM
Message: From FrmDelivery.StartRead(): The scanner not enabled, Call Enable() first.; Inner Ex: ; Stack Trace: at
Symbol.Barcode.Actions.Read(ReaderData rd)
private void StartRead()
{
ExceptionLoggingService.Instance.WriteLog("Reached
frmDelivery.StartRead");
try
{
// If we have both a reader and a reader data
if ((this.barcodeReader != null) && (this.barcodeReaderData !=
null))
{
if (this.barcodeReaderData.IsPending) return;
// Submit a read
this.barcodeReader.ReadNotify += this.barcodeEventHandler;
this.barcodeReader.Actions.Read(this.barcodeReaderData);
}
}
catch (Exception ex)
{
String msgInnerExAndStackTrace = String.Format(
"{0}; Inner Ex: {1}; Stack Trace: {2}", ex.Message,
ex.InnerException, ex.StackTrace);
ExceptionLoggingService.Instance.WriteLog(String.Format("From
FrmDelivery.StartRead(): {0}", msgInnerExAndStackTrace));
}
}
然而,在打开Find表单之前,我关闭了FrmDelivery(“此”如下所示):
StartRead()是引发异常的方法:
Message: Reached frmDelivery.StartRead
Date: 2/19/2015 7:39:39 PM
Message: From FrmDelivery.StartRead(): The scanner not enabled, Call Enable() first.; Inner Ex: ; Stack Trace: at
Symbol.Barcode.Actions.Read(ReaderData rd)
private void StartRead()
{
ExceptionLoggingService.Instance.WriteLog("Reached
frmDelivery.StartRead");
try
{
// If we have both a reader and a reader data
if ((this.barcodeReader != null) && (this.barcodeReaderData !=
null))
{
if (this.barcodeReaderData.IsPending) return;
// Submit a read
this.barcodeReader.ReadNotify += this.barcodeEventHandler;
this.barcodeReader.Actions.Read(this.barcodeReaderData);
}
}
catch (Exception ex)
{
String msgInnerExAndStackTrace = String.Format(
"{0}; Inner Ex: {1}; Stack Trace: {2}", ex.Message,
ex.InnerException, ex.StackTrace);
ExceptionLoggingService.Instance.WriteLog(String.Format("From
FrmDelivery.StartRead(): {0}", msgInnerExAndStackTrace));
}
}
//StartRead()在FrmDelivery中被称为四个位置:
private void textBoxUPC_PLU_GotFocus(object sender, EventArgs e)
{
textBoxUPC_PLU.BackColor = HHSConsts.BARSCAN_COLOR; // Why is this
not sticking?
ExceptionLoggingService.Instance.WriteLog("Reached
frmDelivery.textBoxUPC_PLU_GotFocus");
if (this.InitReader())
{
this.StartRead();
}
}
private void BarcodeReader_ReadNotify(object sender, EventArgs e)
{
ExceptionLoggingService.Instance.WriteLog("Reached
frmDelivery.BarcodeReader_ReadNotify");
try
{
Symbol.Barcode.ReaderData TheReaderData =
this.barcodeReader.GetNextReaderData();
if (TheReaderData.Result == Symbol.Results.SUCCESS)
{
// Handle the data from this read
this.HandleData(TheReaderData);
// Start the next read
this.StartRead();
}
}
catch (Exception ex)
{
String msgInnerExAndStackTrace = String.Format(
"{0}; Inner Ex: {1}; Stack Trace: {2}", ex.Message,
ex.InnerException, ex.StackTrace);
ExceptionLoggingService.Instance.WriteLog(String.Format("From
FrmDelivery.BarcodeReader_ReadNotify(): {0}",
msgInnerExAndStackTrace));
}
}
private void ReaderForm_Activated(object sender, EventArgs e)
{
ExceptionLoggingService.Instance.WriteLog("Reached
frmDelivery.ReaderForm_Activated");
// If there are no reads pending on barcodeReader, start a new read
if (!this.barcodeReaderData.IsPending)
{
this.StartRead();
}
}
private void textBoxId_GotFocus(object sender, EventArgs e)
{
ExceptionLoggingService.Instance.WriteLog("Reached
frmDelivery.textBoxId_GotFocus");
if (this.InitReader())
{
this.StartRead();
}
}
但是,在表单关闭后,这些方法中的任何一个如何调用StartRead()
…在表单关闭后,这些方法中的任何一个如何调用StartRead()
那要看情况。条形码阅读器对象是否仍然存在?也就是说,是否有任何引用
关闭窗体可执行以下两项操作之一,具体取决于窗体是否为模态窗口:隐藏窗口(对于模态窗口)或关闭并处理窗口(对于非模态窗口)。这几乎就是您所能保证的(不包括您添加的其他逻辑,例如FormClosed
事件处理程序)
特别是,关闭表单本身不会以任何方式导致该对象被垃圾收集或以其他方式禁用。许多表单仅由Winforms框架引用,关闭时,这些引用将被丢弃。但是,如果您做了任何事情使表单在其他地方被引用,它将继续存在
您的FrmDelivery
表单似乎已订阅条形码阅读器对象的ReadNotify
事件。这涉及到将委托实例添加到事件的调用列表中,并且由于事件处理程序方法是实例方法,因此该委托实例包括对FrmDelivery
对象的引用
只要条形码阅读器对象仍然是可访问的(或者如果它是一个静态
类,因此其所有成员始终是可访问的),这意味着FrmDelivery
对象也仍然是可访问的。也就是说,条形码阅读器对象保留代理对象,代理对象反过来引用FrmDelivery
对象
由于事件处理程序方法实际上是调用StartRead()
方法的一种方式,因此很可能这就是实际情况。您的代码示例中没有足够的上下文,任何阅读它的人都无法绝对确定,但可能性非常高。这是一个很好的赌注
顺便说一句,除了事件处理程序订阅(从问题描述来看,它看起来无论如何都会使
FrmDelivery
对象保持活动状态)之外,您似乎还在以某种方式嵌套ShowDialog()
调用,以防止收集FrmDelivery
对象
具体来说:您正在事件处理程序中的FrmDelivery
对象上为表单上的按钮调用Close()
。在该处理程序中的ShowDialog()
方法调用返回之前,该处理程序不会返回;在该处理程序返回之前,ShowDialog()
窗口的原始ShowDialog()
调用无法返回,直到该ShowDialog()
调用返回,该方法的调用方无法处置或放弃表单实例
这与是否调用事件处理程序本身无关,但它确实会影响对象的生存期。我很困惑:您说Find表单正在崩溃,但日志摘录似乎说frmDelivery是源,也就是说在第一个代码块中关闭的表单。无论如何,frmDelivery也是一个对话框吗?是的,这是我的问题-为什么一个封闭窗体的事件会触发?通过ShowDialog()从frmMain调用FrmDelivery;使用ShowDialog()从FrmDelivery调用frmFind。旁注:
this.barcodereder.ReadNotify+=this.barcodeventhandler
看起来很麻烦,因为它似乎一直在多次添加此事件处理程序。这可能会使该方法运行多次。@LarsTech:那么,将该代码移到构造函数中,还是先将处理程序解钩,然后再将其连接(-=)?