本文介绍了多次使用DLL时,如何防止DLL引起问题?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

彼得·杜尼奥(Peter Duniho)在评论中指出的此处,当我本应全神贯注于其他事物时,我却被束之高阁.

As Peter Duniho points out in a comment here, I was fixated on a red herring when I should have been focusing on something else altogether.

当我以一种形式使用Symbol.Barcode.Reader和Symbol.Barcode.ReaderData时,它们可以正常工作.我在文档此处.

When I use Symbol.Barcode.Reader and Symbol.Barcode.ReaderData in one form, they work fine. I use them as I document here.

但是,当我从使用条形码扫描代码的一种形式转换为也使用条形码扫描代码的另一种形式时,所有达拉斯都会崩溃.在第二种形式的启动时,我得到以下异常:

However, when I go from one form that uses the barcode scanning code to another one that also does, all Dallas breaks loose. I get the following exception in the second form, on startup:

Symbol.Exceptions.OperationFailureException: SCAN_GetInterfaceParams
   at Symbol.Barcode.InterfaceParams.GetInterfaceParams()
   at Symbol.Barcode.InterfaceParams..ctor(Reader reader)
   at Symbol.Barcode.Actions.Enable()
   at HHS.frmFind.InitReader()
   at HHS.frmFind.textBoxScan_GotFocus(Object sender, EventArgs e)
   at System.Windows.Forms.Control.OnGotFocus(EventArgs e)
   at System.Windows.Forms.Control.WnProc(WM wm, Int32 wParam, Int32 lParam)
   at System.Windows.Forms.Control._InternalWnProc(WM wm, Int32 wParam, Int32 lParam)
   at Microsoft.AGL.Forms.WL.SetVis(IntPtr hwnThis, BOOL fVis)
   at System.Windows.Forms.Control.set_Visible(Boolean value)
   at System.Windows.Forms.Form.ShowDialog()

这两种形式之间的条形码扫描代码是相同的,因此它不是代码本身(第一次使用,在第一种形式中可以正常工作).

The barcode scanning code between the two forms is identical, so it's not the code itself (it works fine the first time, in the first form).

输入设置为扫描的文本框时,第二种形式立即发生异常.之所以触发GotFocus()事件,是因为在显示表单时文本框获得了焦点. OnGotFocus()调用InitReader(),然后失败. InitReader()是:

The exception occurs immediately in the second form when the textbox that is set up for scanning is entered. It's GotFocus() event fires because the textbox gets focus when the form is displayed; OnGotFocus() calls InitReader(), which then fails. InitReader() is:

private bool InitReader()
{
    ExceptionLoggingService.Instance.WriteLog("Reached frmFind.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;
}

要处理的对象位于Motorola的Symbol.Barcode.dll中.它们以如下形式声明:

The objects being dealt with there are in Symbol.Barcode.dll, from Motorola. They are declared in the form like so:

private Symbol.Barcode.Reader barcodeReader;
private Symbol.Barcode.ReaderData barcodeReaderData;

如果我绕过第一个具有相同类型条形码扫描码的表格,并直接转到该表格,它不会崩溃.

If I bypass the first form, which has the same type of barcode scannig code, and go straight to this form, it doesn't crash.

因此,显然,紧密相关的代码位不能共存.为什么不这样做,更重要的是,如何防止这种令人反感的发展?

So apparently it's that the closely related bits of code can't coexist. Why not and, more importantly, how can I prevent this revolting development?

将此日志添加到InitReader中:

With this logging added to InitReader:

private bool InitReader()
{
    ExceptionLoggingService.Instance.WriteLog("Reached frmFind.InitReader");
    // If reader is already present then retreat
    if (this.barcodeReader != null)
    {
        return false;
    }

    // Create new reader, first available reader will be used.
    ExceptionLoggingService.Instance.WriteLog("Reached frmFind.InitReader #2");
    this.barcodeReader = new Symbol.Barcode.Reader();

    // Create reader data
    ExceptionLoggingService.Instance.WriteLog("Reached frmFind.InitReader #3");
    this.barcodeReaderData = new Symbol.Barcode.ReaderData(
        Symbol.Barcode.ReaderDataTypes.Text,
        Symbol.Barcode.ReaderDataLengths.MaximumLabel);

    // Create event handler delegate
    ExceptionLoggingService.Instance.WriteLog("Reached frmFind.InitReader #4");
    this.barcodeEventHandler = this.BarcodeReader_ReadNotify;

    // Enable reader, with wait cursor
    ExceptionLoggingService.Instance.WriteLog("Reached frmFind.InitReader #5");
    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
    ExceptionLoggingService.Instance.WriteLog("Reached frmFind.InitReader #6");
    this.Activated += ReaderForm_Activated;
    this.Deactivate += ReaderForm_Deactivate;

    ExceptionLoggingService.Instance.WriteLog("Reached frmFind.InitReader #7");
    return true;
}

...打开查找"表单并使应用崩溃后,我在日志文件中看到了此信息(它挂起约20秒钟,然后消失):

...I see this in the log file after opening the Find form and crashing the app (it hangs for about 20 seconds before disappearing):

Date: 3/19/2009 11:43:38 PM
Message: Reached frmFind.InitReader

Date: 3/19/2009 11:43:38 PM
Message: Reached frmFind.I

...因此,在这段代码块之后,它几乎立即崩溃:

...so it's crashing almost instantaneously after this block of code:

if (this.barcodeReader != null)
{
    return false;
}

...因为它只经过下一个日志记录行的一半,然后才无礼地打断自己.

...as it only gets through half of the next logging line before rudely interrupting itself.

Fejesjoco可能仍然正确(在下面的评论中),但我将此记录代码提交为展览"A":

Fejesjoco may still be right (in his comment below), but I submit this logging code as exhibit "A":

public void WriteLog(string message)
{
    if (!HHSConsts.Logging) return;
    StringBuilder formattedMessage = new StringBuilder();
    formattedMessage.AppendLine("Date: " + DateTime.Now.ToString());
    formattedMessage.AppendLine("Message: " + message);
    _streamWriter.WriteLine(formattedMessage.ToString());
    _streamWriter.Flush();
}

每行写入日志后,流应该被刷新.

The stream should get flushed after each line is written to the log.

关于故障在崩溃之前挂起"多长时间总是很一致的;我可以在查找表单的条形码文本框中看到光标闪烁,并且它脉动约20次(我上次实际上算过:24次).

The failure is always very consistent as to how long it "hangs" before it crashes; I can see the cursor blinking in the bar code text box of the find form, and it pulsates about 20 times (I actually counted it last time: 24).

这也有点奇怪;在更新2中,我显示了日志文件的内容,所有日志条目均散布在InitReader方法中.注释掉那些注释(第一个注释除外)后,日志文件结尾为:

This also is a bit odd; in Update 2, I showed the contents of the log file with all the log entries sprinkled into the InitReader method. With those commented out (except for the first one), the log file ends with:

Date: 3/20/2009 12:01:22 AM
Message: Reached frmFind.InitReader

Date: 3/20/2009 12:01:22 AM
Message: From application-wide exception handler: Symbol.Exceptions.OperationFailureException: SCAN_GetInterfaceParams
   at Symbol.Barcode.InterfaceParams.GetInterfaceParams()
   at Symbol.Barcode.InterfaceParams..ctor(Reader reader)
   at Symbol.Barcode.Actions.Enable()
   at HHS.frmFind.InitReader()

...因此其他日志文件条目阻止了异常msg的记录.

...so the additional log file entries were preventing the exception msg from getting logged.

Actions.Enable?

Actions.Enable?

当我添加动作"时,我对此并不熟悉.我可以在Symbol.Barcode.Actions和Symbol.Generic.Actions之间进行选择.

I was unfamiliar with this, and when I added "Actions." I got a choice between Symbol.Barcode.Actions and Symbol.Generic.Actions.

我选择了第一个,但它没有启用"方法.加上它后,我被骂:非静态字段,方法或属性'Symbol.Generic.Actions.Enable()'需要对象引用"

I chose the first first, but it has no "Enable" method. Adding it scolded me with, "An object reference is required for the non-static field, method, or property 'Symbol.Generic.Actions.Enable()'"

然后我注释掉添加的用法,输入操作".再次,这次选择了Symbol.Generic.Actions(为我的麻烦得到了同样的错误消息).

I then commented out the using that was added, entered "Actions." again, and this time chose Symbol.Generic.Actions (and got the same err msg for my troubles).

如何使用Actions.Enable()?

How can I use Actions.Enable()?

C.Evenhuis:某些事件每次发生都需要重新附加",您的意思是:

C.Evenhuis: by "some events require re-attaching each time they occur" do you mean this:

private void 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 StopRead()
{
    // If we have a reader
    if (this.barcodeReader != null)
    {
        // Flush (Cancel all pending reads)
        this.barcodeReader.ReadNotify -= this.barcodeEventHandler;
        this.barcodeReader.Actions.Flush();
    }
}

...(在StartRead中附加了barcodeReader.ReadNotify,在StopRead中附加了它)?

...(barcodeReader.ReadNotify is attached in StartRead and detached in StopRead), or is more necessary?

我在InitReader()中也有

I also have, in InitReader():

this.Activated += ReaderForm_Activated;
this.Deactivate += ReaderForm_Deactivate;

...实现方式如下:

...which are implemented like so:

private void ReaderForm_Activated(object sender, EventArgs e)
{
    // 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)
{
    this.StopRead();
}

从textBoxScan_GotFocus()调用InitReader();表单显示时textBoxScan会成为焦点.

InitReader() is called from textBoxScan_GotFocus(); textBoxScan has the focus when the form displays.

关于在关闭Dispose()之前先明确关闭()类",我在两个对象上调用Dispose,即Symbol.Barcode.Reader和Symbol.Barcode.ReaderData,并且都不允许使用Close()调用.

As to "Explicitly Close() classes before you Dispose() them", I call Dispose on two things, Symbol.Barcode.Reader and Symbol.Barcode.ReaderData, and neither one allows a Close() call.

C.Evenhuis的这句话:您不能启用两个(前台)阅读器",导致我尝试以下操作:

This statement from C. Evenhuis: "you can't have two (foreground) readers enabled" led me to try the following:

private void FrmDelivery_Closing(object sender, System.ComponentModel.CancelEventArgs e)
{
    this.barcodeReader.Actions.Disable();
}

...这似乎已经完成了很多工作-我可以打开查找"表单而不会挂起,导致最终崩溃.扫描到交货"表单后,我可以扫描到查找"表单.我仍然看到的唯一(不相关?)问题是,由于某种原因,我的查找"表单仍被部分遮盖了...

...which seems to have pretty much done the trick - I can open the Find form without a hang resulting in an eventual crash. I can scan into the Find form after having scanned into the Delivery form. The only (unrelated?) problem that I still see is that my Find form is still partially obscured for some reason...

推荐答案

Zebra正在基于具有旧版.NET包装器的旧版C ++库中构建.有很多陷阱(某些事件每次发生时都需要重新连接,某些类在您Dispose()之前需要显式的Close(),等等.)

Zebra is building on a legacy C++ library with a legacy .NET wrapper. There are quite some pitfalls (some events require re-attaching each time they occur, some classes require explicit Close() before you Dispose() them, etc).

您可能已经发现,可以从多个线程/窗体调用Symbol类的成员,但是不能启用两个(前台)读取器,并且只有在未启用后台读取器的情况下才能设置某些属性,并且无法确定是否启用了 后台读取器(即DataWedge).

As you may have found out, you can invoke members of the Symbol classes from multiple threads / forms, but you can't have two (foreground) readers enabled, and some properties can only be set if no background readers are enabled, and there is no way to determine whether there are background readers enabled (ie DataWedge).

在我们公司,我们选择在Form.Activated事件中初始化扫描仪,然后在Deactivated事件中取消初始化扫描仪.然后,当需要扫描时,调用Actions.Enable()即可解决问题.设置阅读器属性是在try catch块中完成的:(

At our company we chose to initialize the scanner in the Form.Activated event and deinitialize it in the Deactivated event. Then when scanning was required, a call to Actions.Enable() would do the trick. Setting reader properties is done in try catch blocks :(

奇怪的是,您的应用程序在 Get InterfaceParams崩溃,我希望设置会引起麻烦.尝试最低限度的应用程序;不要设置BeepTimeWaveFile属性.

Quite odd that your application crashes at GetInterfaceParams, I would expect Setting them to cause trouble. Try your application with the bare minimum; don't set the BeepTime or WaveFile properties.

这篇关于多次使用DLL时,如何防止DLL引起问题?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

08-04 00:45