为什么NRE会在成功运作后发生? [英] Why would this NRE occur after a successful operation?
问题描述
消息:从应用程序范围的异常处理程序:System.NullReferenceException:NullReferenceException $ h $。 e)
在System.Windows.Forms.Form.WnProc(WM wm,Int32 wParam,Int32 lParam)
在System.Windows.Forms.Control._InternalWnProc(WM wm,Int32 wParam,Int32 lParam)
在Microsoft.AGL.Forms.DLG.MessageBox(String wszCaption,String wszBody,MessageBoxButtons mbtyp,MessageBoxIcon mbicon,MessageBoxDefaultButton defbtn,DialogResult& mbret)
在System.Windows.Forms.MessageBox.Show(String文本,字符串标题,MessageBoxButtons按钮,MessageBoxIcon图标,MessageBoxDefaultButton defaultButton)
在HHS.FrmDelivery.buttonSave_Click(Object sender,EventArgs args)
所以问题似乎在FrmDelivery.ReaderForm_Activated()中,这是处理条形码扫描的窗体代码的一部分: / p>
private void ReaderForm_Activated(object sender,EventArgs e)
{
ExceptionLoggingService.Instance.WriteLog(Reached frmDelivery.ReaderForm_Activated);
//如果条形码没有读取挂起,读取器将启动一个新的读取
if(!this.barcodeReaderData.IsPending)
{
this.StartRead();
}
}
在上下文中,这是整个条码扫描相关该表单上的代码:
public partial class FrmDelivery:Form
{
。 。 。
//条形码东西
private Symbol.Barcode.Reader barcodeReader;
private Symbol.Barcode.ReaderData barcodeReaderData;
private EventHandler barcodeEventHandler;
//< / Barcode stuff
// form的重载构造函数
public FrmDelivery(NewDelivery newDel)
{
InitializeComponent();
。 。 。
textBoxUPC_PLU.Focus();
}
//条形码扫描代码
private void textBoxUPC_PLU_GotFocus(object sender,EventArgs e)
{
ExceptionLoggingService.Instance.WriteLog(Reached frmDelivery .textBoxUPC_PLU_GotFocus);
if(this.InitReader())
{
this.StartRead();
}
}
private bool InitReader()
{
ExceptionLoggingService.Instance.WriteLog(Reached frmDelivery.InitReader);
//如果读者已经存在,则撤销
if(this.barcodeReader!= null)
{
return false;
}
//创建新的阅读器,首先使用读者将被使用。
this.barcodeReader = new Symbol.Barcode.Reader();
//创建读取器数据
this.barcodeReaderData = new Symbol.Barcode.ReaderData(
Symbol.Barcode.ReaderDataTypes.Text,
Symbol.Barcode.ReaderDataLengths。 MaximumLabel);
//创建事件处理程序委托
this.barcodeEventHandler = this.BarcodeReader_ReadNotify;
//启用阅读器,等待游标
this.barcodeReader.Actions.Enable();
this.barcodeReader.Parameters.Feedback.Success.BeepTime = 0;
this.barcodeReader.Parameters.Feedback.Success.WaveFile =\\windows\\alarm3.wav;
//附加激活和停用事件
this.Activated + = ReaderForm_Activated;
this.Deactivate + = ReaderForm_Deactivate;
返回true;
}
private void StartRead()
{
ExceptionLoggingService.Instance.WriteLog(Reached frmDelivery.StartRead);
//如果我们同时拥有读写器数据
if((this.barcodeReader!= null)&(this.barcodeReaderData!= null))
{
//提交读取
this.barcodeReader.ReadNotify + = this.barcodeEventHandler;
this.barcodeReader.Actions.Read(this.barcodeReaderData);
}
}
private void BarcodeReader_ReadNotify(object sender,EventArgs e)
{
ExceptionLoggingService.Instance.WriteLog(Reached frmDelivery.BarcodeReader_ReadNotify) ;
Symbol.Barcode.ReaderData TheReaderData = this.barcodeReader.GetNextReaderData();
//如果它是一个成功的读取(而不是失败的一个)
if(TheReaderData.Result == Symbol.Results.SUCCESS)
{
//处理这个读取的数据
this.HandleData(TheReaderData);
//开始下一个读取
this.StartRead();
}
}
private void ReaderForm_Activated(object sender,EventArgs e)
{
ExceptionLoggingService.Instance.WriteLog(Reached frmDelivery.ReaderForm_Activated) ;
//如果条形码没有读取挂起,读取器将启动一个新的读取
if(!this.barcodeReaderData.IsPending)
{
this.StartRead();
}
}
private void ReaderForm_Deactivate(object sender,EventArgs e)
{
ExceptionLoggingService.Instance.WriteLog(Reached frmDelivery.ReaderForm_Deactivate) ;
this.StopRead();
}
private void HandleData(Symbol.Barcode.ReaderData readerData)
{
ExceptionLoggingService.Instance.WriteLog(Reached frmDelivery.HandleData);
textBoxUPC_PLU.Text = readerData.Text;
//现在将其移动到下一个非read-only textBox
textBoxPackSize.Focus();
}
private void StopRead()
{
ExceptionLoggingService.Instance.WriteLog(Reached frmDelivery.StopRead);
//如果我们有一个读者
if(this.barcodeReader!= null)
{
// Flush(取消所有待处理的读取)
this.barcodeReader。 ReadNotify - = this.barcodeEventHandler;
this.barcodeReader.Actions.Flush();
}
}
private void textBoxUPC_PLU_LostFocus(object sender,EventArgs e)
{
ExceptionLoggingService.Instance.WriteLog(Reached frmDelivery.textBoxUPC_PLU_LostFocus) ;
this.DisposeBarcodeReaderAndData();
}
private void DisposeBarcodeReaderAndData()
{
ExceptionLoggingService.Instance.WriteLog(Reached frmDelivery.DisposeBarcodeReaderAndData);
//如果我们有一个读者
if(this.barcodeReader!= null)
{
//禁用读者
this.barcodeReader.Actions.Disable( );
//释放它
this.barcodeReader.Dispose();
//指示我们不再有一个
this.barcodeReader = null;
}
//如果我们有一个读者数据
if(this.barcodeReaderData!= null)
{
//释放
this.barcodeReaderData.Dispose();
//指示我们不再有一个
this.barcodeReaderData = null;
}
}
...这里是被称为在异常发生之前。 已达到frmDelivery.buttonSave_Click已被记录,并且我看到已保存的传送,但应用程序之后立即崩溃:
private void buttonSave_Click(object sender,EventArgs args)
{
ExceptionLoggingService.Instance.WriteLog(Reached frmDelivery.buttonSave_Click);
if(RequiredDataMissing())
{
this.IndicateMissingData();
return;
}
this.PrepareForNewDSDTable();
SaveDSDHeaderRecord();
SaveWorkTableRecord();
//现在可以搜索记录
buttonFind.Enabled = true;
MessageBox.Show(Delivery saved);
}
...这里是日志文件的摘录(从时间SaveWorkTableRecord()被调用直到洪水):
日期:3/13/2009 6:41:34 PM b $ b消息:达到frmDelivery.SaveWorkTableRecord
日期:3/13/2009 6:41:34 PM
消息:达到HHSUtils.TryConvertToInt32
日期: 3/13/2009 6:41:34 PM
消息:达到HHSUtils.TryConvertToDecimal
日期:3/13/2009 6:41:34 PM
消息:达到SQliteHHSDBUtils日期:3/13/2009 6:41:34 PM
消息:达到HHSUtils.GetDBConnection
日期:3/13/2009 6: 41:34 PM
消息:达到frmDelivery.ReaderForm_Deactivate
日期:3/13/2009 6:41:34 PM
消息:已达到frmDelivery.StopRead
日期:3/13/2009 6:41:37 PM
消息:达到frmDelivery.ReaderForm_Activated
日期:3/13/2009 6:41:37 PM
消息:从应用程序范围的异常处理程序:System.NullReference例外:System.Windows.Form.OnActivated(EventArgs e)
在System.Windows.Forms.Form中.WnProc(WM wm,Int32 wParam,Int32 lParam)
在System.Windows.Forms.Control._InternalWnProc(WM wm,Int32 wParam,Int32 lParam)
在Microsoft.AGL.Forms.DLG.MessageBox (String wszCaption,String wszBody,MessageBoxButtons mbtyp,MessageBoxIcon mbicon,MessageBoxDefaultButton defbtn,DialogResult& mbret)
在System.Windows.Forms.MessageBox.Show(String text,String caption,MessageBoxButtons buttons,MessageBoxIcon icon,MessageBoxDefaultButton defaultButton)
在HHS.FrmDelivery.buttonSave_Click(Object sender,EventArgs args)$在System.Windows.Forms.Control.OnClick(EventArgs e)上的
在System.Windows.Forms.Button.OnClick(EventArgs e)
在System.Windows.Forms.ButtonBase.WnProc( WM wm,Int32 wParam,Int32 lParam)
在System.Windows.Forms.Control._InternalWnProc(WM wm,Int32 wParam,Int32 lParam)
在Microsoft.AGL.Forms.EVL.EnterMainLoop(IntPtr hwnMain )
在System.Windows.Forms.Application.Run(Form fm)
在HHS.Program.Main()
不要注意日期;手持设备(有些适合)生活在过去。
以下是最后一次成功调用的方法:
private void SaveWorkTableRecord ()
{
ExceptionLoggingService.Instance.WriteLog(Reached frmDelivery.SaveWorkTableRecord);
WorkTable wt = new WorkTable
{
WTName = this.dsdName,
SiteNum = this.nd.SiteNum,
FileType =DSD,
FileDate = this.nd.DeliveryDate,
TotalItems = HHSUtils.TryConvertToInt32(this.textBoxQty.Text.Trim()),
TotalAmount =
HHSUtils.TryConvertToDecimal(this.textBoxTotalDollar.Text.Trim ())
};
hhsdbutils.InsertWorkTableRecord(wt);
}
为什么条形码读取器和/或barcodeReaderData(显然)为空,当它们是在InitReader()中实例化,在构造表单时调用?
更新
即使使用barcodereader和barcodereaderData代码移动到FormClosing(),我仍然得到一个NRE:
日期:3/13/2009 8:10:08 PM
消息:达到frmDelivery.DisposeBarcodeReaderAndData
日期:3/13/2009 8:10:08 PM
消息:达到HHSUtils.TextBoxLostFocus
日期:3/13/2009 8:10:08 PM
消息:达到frmDelivery.buttonClose_Click
日期:3/13/2009 8:10:12 PM
消息:达到frmDelivery.ReaderForm_Deactivate
日期:3/13/2009 8:10:12 PM
消息:达到frmDelivery.StopRead
日期: 3/13/2009 8:10:13 PM
消息:达到frmDelivery.BarcodeReader_ReadNotify
日期:3/13/2009 8:10:13 PM
消息:从应用程序范围内xception处理程序:System.NullReferenceException:NullReferenceException在HHS.FrmDelivery.BarcodeReader_ReadNotify(Object sender,EventArgs e)中的
System.Windows.Forms.Control.TASK.Invoke()
在System处。更新2
更新:我把这段代码移动到FormClosing(),但是在关闭应用程序后有一个NRE?评论代码在那里(条码阅读器和条码阅读器数据不再被处理/取消任何地方)纠正了这个问题 - 没有更多的NRE。
解决方案 p>注释处理条码阅读器和条码阅读器数据对象的代码是诀窍:
private void DisposeBarcodeReaderAndData()
{
ExceptionLoggingService.Instance.WriteLog(Reached frmDelivery.DisposeBarcodeReaderAndData);
//注释出来,看看是否阻止了NRE;如果是,请尝试将其移动到FromClose或FormClosing或类似的
////如果我们有一个读者
// if(this.barcodeReader!= null)
// {
// //禁用读者
// this.barcodeReader.Actions.Disable();
// //释放它
// this.barcodeReader.Dispose();
// //指示我们不再有一个
// this.barcodeReader = null;
//}
////如果我们有一个读者数据
// if(this.barcodeReaderData!= null)
// {
// //释放它
// this.barcodeReaderData.Dispose();
// //指示我们不再有一个
// this.barcodeReaderData = null;
//}
}
...但是我应该处理/取消这些在formClosing或formClose,或者是那么模糊吗?
更新:我把这段代码移动到FormClosing(),但是在关闭应用程序后有一个NRE。 ..?!?对代码进行评论(条码阅读器和条码阅读器数据不再在任何地方处理/取消)纠正了这个问题 - 不再有NRE。
I have a project-wide exception handler in my Windows CE app that is logging this when my app crashes in a specific scenario:
Message: From application-wide exception handler: System.NullReferenceException: NullReferenceException
at HHS.FrmDelivery.ReaderForm_Activated(Object sender, EventArgs e)
at System.Windows.Forms.Form.OnActivated(EventArgs e)
at System.Windows.Forms.Form.WnProc(WM wm, Int32 wParam, Int32 lParam)
at System.Windows.Forms.Control._InternalWnProc(WM wm, Int32 wParam, Int32 lParam)
at Microsoft.AGL.Forms.DLG.MessageBox(String wszCaption, String wszBody, MessageBoxButtons mbtyp, MessageBoxIcon mbicon, MessageBoxDefaultButton defbtn, DialogResult& mbret)
at System.Windows.Forms.MessageBox.Show(String text, String caption, MessageBoxButtons buttons, MessageBoxIcon icon, MessageBoxDefaultButton defaultButton)
at HHS.FrmDelivery.buttonSave_Click(Object sender, EventArgs args)
So the problem seems to be in FrmDelivery.ReaderForm_Activated(), which is part of the form's code to deal with barcode scanning:
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();
}
}
In context, here is the entire barcode scanning-related code on that form:
public partial class FrmDelivery : Form
{
. . .
// Barcode stuff
private Symbol.Barcode.Reader barcodeReader;
private Symbol.Barcode.ReaderData barcodeReaderData;
private EventHandler barcodeEventHandler;
// </ Barcode stuff
// form's overloaded constructor
public FrmDelivery(NewDelivery newDel)
{
InitializeComponent();
. . .
textBoxUPC_PLU.Focus();
}
// Barcode scanning code
private void textBoxUPC_PLU_GotFocus(object sender, EventArgs e)
{
ExceptionLoggingService.Instance.WriteLog("Reached frmDelivery.textBoxUPC_PLU_GotFocus");
if (this.InitReader())
{
this.StartRead();
}
}
private bool InitReader()
{
ExceptionLoggingService.Instance.WriteLog("Reached frmDelivery.InitReader");
// If reader is already present then retreat
if (this.barcodeReader != null)
{
return false;
}
// Create new reader, first available reader will be used.
this.barcodeReader = new Symbol.Barcode.Reader();
// Create reader data
this.barcodeReaderData = new Symbol.Barcode.ReaderData(
Symbol.Barcode.ReaderDataTypes.Text,
Symbol.Barcode.ReaderDataLengths.MaximumLabel);
// Create event handler delegate
this.barcodeEventHandler = this.BarcodeReader_ReadNotify;
// Enable reader, with wait cursor
this.barcodeReader.Actions.Enable();
this.barcodeReader.Parameters.Feedback.Success.BeepTime = 0;
this.barcodeReader.Parameters.Feedback.Success.WaveFile = "\\windows\\alarm3.wav";
// Attach to activate and deactivate events
this.Activated += ReaderForm_Activated;
this.Deactivate += ReaderForm_Deactivate;
return true;
}
private void StartRead()
{
ExceptionLoggingService.Instance.WriteLog("Reached frmDelivery.StartRead");
// If we have both a reader and a reader data
if ((this.barcodeReader != null) && (this.barcodeReaderData != null))
{
// Submit a read
this.barcodeReader.ReadNotify += this.barcodeEventHandler;
this.barcodeReader.Actions.Read(this.barcodeReaderData);
}
}
private void BarcodeReader_ReadNotify(object sender, EventArgs e)
{
ExceptionLoggingService.Instance.WriteLog("Reached frmDelivery.BarcodeReader_ReadNotify");
Symbol.Barcode.ReaderData TheReaderData = this.barcodeReader.GetNextReaderData();
// If it is a successful read (as opposed to a failed one)
if (TheReaderData.Result == Symbol.Results.SUCCESS)
{
// Handle the data from this read
this.HandleData(TheReaderData);
// Start the next read
this.StartRead();
}
}
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 ReaderForm_Deactivate(object sender, EventArgs e)
{
ExceptionLoggingService.Instance.WriteLog("Reached frmDelivery.ReaderForm_Deactivate");
this.StopRead();
}
private void HandleData(Symbol.Barcode.ReaderData readerData)
{
ExceptionLoggingService.Instance.WriteLog("Reached frmDelivery.HandleData");
textBoxUPC_PLU.Text = readerData.Text;
// now move off of it to next non-read-only textBox
textBoxPackSize.Focus();
}
private void StopRead()
{
ExceptionLoggingService.Instance.WriteLog("Reached frmDelivery.StopRead");
// If we have a reader
if (this.barcodeReader != null)
{
// Flush (Cancel all pending reads)
this.barcodeReader.ReadNotify -= this.barcodeEventHandler;
this.barcodeReader.Actions.Flush();
}
}
private void textBoxUPC_PLU_LostFocus(object sender, EventArgs e)
{
ExceptionLoggingService.Instance.WriteLog("Reached frmDelivery.textBoxUPC_PLU_LostFocus");
this.DisposeBarcodeReaderAndData();
}
private void DisposeBarcodeReaderAndData()
{
ExceptionLoggingService.Instance.WriteLog("Reached frmDelivery.DisposeBarcodeReaderAndData");
// If we have a reader
if (this.barcodeReader != null)
{
// Disable the reader
this.barcodeReader.Actions.Disable();
// Free it up
this.barcodeReader.Dispose();
// Indicate we no longer have one
this.barcodeReader = null;
}
// If we have a reader data
if (this.barcodeReaderData != null)
{
// Free it up
this.barcodeReaderData.Dispose();
// Indicate we no longer have one
this.barcodeReaderData = null;
}
}
...and here is the code that is called prior to the exception occurring. "Reached frmDelivery.buttonSave_Click" is logged, and I do see the "Delivery saved" but the app crashes immediately thereafter:
private void buttonSave_Click(object sender, EventArgs args)
{
ExceptionLoggingService.Instance.WriteLog("Reached frmDelivery.buttonSave_Click");
if (RequiredDataMissing())
{
this.IndicateMissingData();
return;
}
this.PrepareForNewDSDTable();
SaveDSDHeaderRecord();
SaveWorkTableRecord();
// Now can search the record
buttonFind.Enabled = true;
MessageBox.Show("Delivery saved");
}
...and here is an excerpt of the log file (from the time SaveWorkTableRecord() is called until the "deluge"):
Date: 3/13/2009 6:41:34 PM
Message: Reached frmDelivery.SaveWorkTableRecord
Date: 3/13/2009 6:41:34 PM
Message: Reached HHSUtils.TryConvertToInt32
Date: 3/13/2009 6:41:34 PM
Message: Reached HHSUtils.TryConvertToDecimal
Date: 3/13/2009 6:41:34 PM
Message: Reached SQliteHHSDBUtils.InsertWorkTableRecord
Date: 3/13/2009 6:41:34 PM
Message: Reached HHSUtils.GetDBConnection
Date: 3/13/2009 6:41:34 PM
Message: Reached frmDelivery.ReaderForm_Deactivate
Date: 3/13/2009 6:41:34 PM
Message: Reached frmDelivery.StopRead
Date: 3/13/2009 6:41:37 PM
Message: Reached frmDelivery.ReaderForm_Activated
Date: 3/13/2009 6:41:37 PM
Message: From application-wide exception handler: System.NullReferenceException: NullReferenceException
at HHS.FrmDelivery.ReaderForm_Activated(Object sender, EventArgs e)
at System.Windows.Forms.Form.OnActivated(EventArgs e)
at System.Windows.Forms.Form.WnProc(WM wm, Int32 wParam, Int32 lParam)
at System.Windows.Forms.Control._InternalWnProc(WM wm, Int32 wParam, Int32 lParam)
at Microsoft.AGL.Forms.DLG.MessageBox(String wszCaption, String wszBody, MessageBoxButtons mbtyp, MessageBoxIcon mbicon, MessageBoxDefaultButton defbtn, DialogResult& mbret)
at System.Windows.Forms.MessageBox.Show(String text, String caption, MessageBoxButtons buttons, MessageBoxIcon icon, MessageBoxDefaultButton defaultButton)
at HHS.FrmDelivery.buttonSave_Click(Object sender, EventArgs args)
at System.Windows.Forms.Control.OnClick(EventArgs e)
at System.Windows.Forms.Button.OnClick(EventArgs e)
at System.Windows.Forms.ButtonBase.WnProc(WM wm, Int32 wParam, Int32 lParam)
at System.Windows.Forms.Control._InternalWnProc(WM wm, Int32 wParam, Int32 lParam)
at Microsoft.AGL.Forms.EVL.EnterMainLoop(IntPtr hwnMain)
at System.Windows.Forms.Application.Run(Form fm)
at HHS.Program.Main()
Pay no attention to the dates; the handheld device is (somewhat fittingly) living in the past.
Here is the last successfully called method:
private void SaveWorkTableRecord()
{
ExceptionLoggingService.Instance.WriteLog("Reached frmDelivery.SaveWorkTableRecord");
WorkTable wt = new WorkTable
{
WTName = this.dsdName,
SiteNum = this.nd.SiteNum,
FileType = "DSD",
FileDate = this.nd.DeliveryDate,
TotalItems = HHSUtils.TryConvertToInt32(this.textBoxQty.Text.Trim()),
TotalAmount =
HHSUtils.TryConvertToDecimal(this.textBoxTotalDollar.Text.Trim())
};
hhsdbutils.InsertWorkTableRecord(wt);
}
So why is barcodeReader and/or barcodeReaderData (apparently) null, when they are instantiated in InitReader(), which is called when the form is constructed?
UPDATE
Even with the barcodereader and barcodereaderData code moved from where it was to FormClosing(), I still get an NRE:
Date: 3/13/2009 8:10:08 PM
Message: Reached frmDelivery.DisposeBarcodeReaderAndData
Date: 3/13/2009 8:10:08 PM
Message: Reached HHSUtils.TextBoxLostFocus
Date: 3/13/2009 8:10:08 PM
Message: Reached frmDelivery.buttonClose_Click
Date: 3/13/2009 8:10:12 PM
Message: Reached frmDelivery.ReaderForm_Deactivate
Date: 3/13/2009 8:10:12 PM
Message: Reached frmDelivery.StopRead
Date: 3/13/2009 8:10:13 PM
Message: Reached frmDelivery.BarcodeReader_ReadNotify
Date: 3/13/2009 8:10:13 PM
Message: From application-wide exception handler: System.NullReferenceException: NullReferenceException
at HHS.FrmDelivery.BarcodeReader_ReadNotify(Object sender, EventArgs e)
at System.Windows.Forms.Control.TASK.Invoke()
at System.Windows.Forms.Control._InvokeAll()
UPDATE 2
Update: I moved this code to FormClosing(), but then got an NRE on shutting down the app...?!? Commenting the code out there, too (barcodeReader and barcodeReaderData no longer being disposed/nullified anywhere) rectified the problem - no more NREs.
解决方案 Commenting out the code that disposes the barcodeReader and barcodeReaderData objects does the trick:
private void DisposeBarcodeReaderAndData()
{
ExceptionLoggingService.Instance.WriteLog("Reached frmDelivery.DisposeBarcodeReaderAndData");
// Commenting out to see if this prevents the NRE; if so, try moving this to FromClose or FormClosing or something similar
//// If we have a reader
//if (this.barcodeReader != null)
//{
// // Disable the reader
// this.barcodeReader.Actions.Disable();
// // Free it up
// this.barcodeReader.Dispose();
// // Indicate we no longer have one
// this.barcodeReader = null;
//}
//// If we have a reader data
//if (this.barcodeReaderData != null)
//{
// // Free it up
// this.barcodeReaderData.Dispose();
// // Indicate we no longer have one
// this.barcodeReaderData = null;
//}
}
...but should I dispose/nullify these on formClosing or formClose, or is that moot by then?
Update: I moved this code to FormClosing(), but then got an NRE on shutting down the app...?!? Commenting the code out there, too (barcodeReader and barcodeReaderData no longer being disposed/nullified anywhere) rectified the problem - no more NREs.
这篇关于为什么NRE会在成功运作后发生?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!