C# &引用;参数计数不匹配“;在WndProc覆盖中发生Form.ShowDialog()之后

C# &引用;参数计数不匹配“;在WndProc覆盖中发生Form.ShowDialog()之后,c#,winforms,exception,message-queue,wndproc,C#,Winforms,Exception,Message Queue,Wndproc,我已经为旧版本的Windows中的Metro Forms实现获取了某人的开源;我打算在将来重新编写,但我现在想“工作” **编辑**::我已经在这个上下文中恢复了System.Windows.Forms的基类,并且仍然产生相同的结果 现在我在WndProc方法中遇到了一个参数计数不匹配异常,该异常已在所述MetroFramework(by/by)中被覆盖 关于这个问题,我可能会与这两位先生中的一位或两位进行磋商,但我认为,以细节开始提问可能会产生更快的结果 **编辑**::我已经删除了对上述项目

我已经为旧版本的Windows中的Metro Forms实现获取了某人的开源;我打算在将来重新编写,但我现在想“工作”

**编辑**::我已经在这个上下文中恢复了System.Windows.Forms的基类,并且仍然产生相同的结果

现在我在
WndProc
方法中遇到了一个
参数计数不匹配
异常,该异常已在所述
MetroFramework
(by/by)中被覆盖

关于这个问题,我可能会与这两位先生中的一位或两位进行磋商,但我认为,以细节开始提问可能会产生更快的结果

**编辑**::我已经删除了对上述项目的表单引用,现在只使用基本表单生成此应用程序的UI。我相信我的下一步是回滚用户控件。我宁愿不要

在这个过程中涉及到两种方法;我有一些调试信息要附加;我们开始吧

每杯葡萄酒;我找到了默认情况下可以传递给WndProc的Windows消息的完整列表。目前看来,我的应用程序的WndProc方法正在接收中未列出的消息

在遇到异常时,在生成异常的线程中,我发现了以下信息:

public partial class BaseProductionDialog : Provectusoft.Forms.MetroForm
{
    protected void PromptAuthentication()
    {
        if (this.DesignMode)
            return;
        else if (this.AuthenticationDialog.Visible)
            throw new Exception("The Media Minutes Live Captioning Production Client Authentication Dialog cannot be shown as it is already visible.");
        else
        {
            // This occurs but never concludes
            DialogResult Result = this.AuthenticationDialog.ShowDialog(this);

            if (Result == System.Windows.Forms.DialogResult.Yes)
            {
                this.BringToFront();

                this.Focus();

                return;
            }
            else
            {
                if (!this.IsAuthenticated)
                {
                    MessageBox.Show("There seems to have been an issue in your authentication. Please try again.");

                    this.PromptAuthentication();

                    return;
                }
                else
                {
                    return;
                }
            }
        }
    }

    public DialogResult ShowDialog(System.Windows.Forms.Form ParentForm)
    {
        if (this.IsAuthenticated)
            return DialogResult.Yes;
        else if( this.InvokeRequired )
            // This never occurs
            return (DialogResult) this.Invoke(new Action(delegate { this.ShowDialog(ParentForm); }));
        else
        {
            // This occurs but never concludes
            DialogResult Result = base.ShowDialog(ParentForm);

            if (this.IsAuthenticated)
                return DialogResult.Yes;
            else
                return DialogResult.No;
        }
    }
}
线程:

'Main Thread'
堆栈跟踪:

**编辑**::这是围绕异常的初始堆栈跟踪。之后是更新的堆栈跟踪,没有MetroForm实现

at System.Reflection.RuntimeMethodInfo.UnsafeInvoke(Object obj, BindingFlags invokeAttr, Binder binder, Object[] parameters, CultureInfo culture)
at System.Delegate.DynamicInvokeImpl(Object[] args)
at System.Windows.Forms.Control.InvokeMarshaledCallbackDo(ThreadMethodEntry tme)
at System.Windows.Forms.Control.InvokeMarshaledCallbackHelper(Object obj)
at System.Threading.ExecutionContext.RunInternal(ExecutionContext executionContext, ContextCallback callback, Object state, Boolean preserveSyncCtx)
at System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state, Boolean preserveSyncCtx)
at System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state)
at System.Windows.Forms.Control.InvokeMarshaledCallback(ThreadMethodEntry tme)
at System.Windows.Forms.Control.InvokeMarshaledCallbacks()
at System.Windows.Forms.Control.WndProc(Message& m)
at MetroFramework.Controls.MetroUserControlBase.WndProc(Message& m) in f:\Users\DigitalJedi\Documents\Development\Projects\C#\Supporting Projects\MetroFramework-master\MetroFramework\Controls\MetroControlBase.cs:line 4129
**编辑**::更新的堆栈跟踪(看起来没有区别):

在WndProc覆盖内:

public class MetroUserControlBase : UserControl, IMetroContainerControl, IMetroControl, IMetroStyledComponent
{
    protected override void WndProc(ref Message m)
    {
        try
        {
            if (DesignMode)
            {
                base.WndProc(ref m);
                return;
            }

            switch (m.Msg)
            {
                //case 0xC2BA:
                    //return;;

                //case WinApi.Messages.WM_CTLCOLORBTN:
                //Debug.WriteLine("WM_CTLCOLORBTN", GetType().Name);
                //break;
                //case WinApi.Messages.WM_CTLCOLORSTATIC:
                //Debug.WriteLine("WM_CTLCOLORSTATIC", GetType().Name);
                //break;
                case WinApi.Messages.WM_CTLCOLOREDIT:
                    Debug.WriteLine("WM_CTLCOLOREDIT", GetType().Name);
                    break;
                case WinApi.Messages.WM_CTLCOLORDLG:
                    Debug.WriteLine("WM_CTLCOLORDLG ", GetType().Name);
                    break;
                case WinApi.Messages.WM_CTLCOLORLISTBOX:
                    Debug.WriteLine("WM_CTLCOLORLISTBOX", GetType().Name);
                    break;
                case WinApi.Messages.WM_CTLCOLORSCROLLBAR:
                    Debug.WriteLine("WM_CTLCOLORSCROLLBAR ", GetType().Name);
                    break;
            }
            // Line 4143
            base.WndProc(ref m);
        }
        catch( Exception e )
        {

        }
    }
}
您会注意到,我已经注释掉了上面代码中的第一个case语句<代码>案例0xC2BA-这是我在此窗口崩溃之前收到的消息。在互联网上搜索了一段时间后,无论是十进制还是十六进制,我都没有发现这是一条正常消息的迹象;然而,我也没有在我继承的项目的源代码中找到它的定义

我已经进一步研究了我的代码中的哪些元素迫使生成此代码,显然,它来自于我在控件父窗体上调用的
ShowDialog
方法

我实现了
ShowDialog
方法,为了调试,我以自己的形式覆盖了这个
ShowDialog
方法,它几乎没有产生任何信息:

public partial class BaseProductionDialog : Provectusoft.Forms.MetroForm
{
    protected void PromptAuthentication()
    {
        if (this.DesignMode)
            return;
        else if (this.AuthenticationDialog.Visible)
            throw new Exception("The Media Minutes Live Captioning Production Client Authentication Dialog cannot be shown as it is already visible.");
        else
        {
            // This occurs but never concludes
            DialogResult Result = this.AuthenticationDialog.ShowDialog(this);

            if (Result == System.Windows.Forms.DialogResult.Yes)
            {
                this.BringToFront();

                this.Focus();

                return;
            }
            else
            {
                if (!this.IsAuthenticated)
                {
                    MessageBox.Show("There seems to have been an issue in your authentication. Please try again.");

                    this.PromptAuthentication();

                    return;
                }
                else
                {
                    return;
                }
            }
        }
    }

    public DialogResult ShowDialog(System.Windows.Forms.Form ParentForm)
    {
        if (this.IsAuthenticated)
            return DialogResult.Yes;
        else if( this.InvokeRequired )
            // This never occurs
            return (DialogResult) this.Invoke(new Action(delegate { this.ShowDialog(ParentForm); }));
        else
        {
            // This occurs but never concludes
            DialogResult Result = base.ShowDialog(ParentForm);

            if (this.IsAuthenticated)
                return DialogResult.Yes;
            else
                return DialogResult.No;
        }
    }
}
为了彻底,;发生异常时,从父进程接收的消息实例如下所示:

Msg = 0xC2BA ( 49850 )
HWnd = 0x1403f2 ( 1311730 )
wparam = 0x0
lparam = 0x0
result = 0x0
遇到问题时,重写方法的
switch
语句已被传递,没有任何case语句条目(除非我取消注释
0xc2ba
行)

最后,我认为这应该已经很清楚了,异常是
TargetParameterCountException
,消息是
参数计数不匹配
。我还检查了输出窗口中的任何信息,我得到的最多信息是:

A first chance exception of type 'System.Reflection.TargetParameterCountException occurred in mscorlib.dll'
我可能会注意到,我使用的控件的基线实现(根据它们引用的项目)确实有效。支持“MetroFramework”解决方案的“demo”项目至少实现了我在自己的实现中使用的所有控件

at System.Reflection.RuntimeMethodInfo.UnsafeInvoke(Object obj, BindingFlags invokeAttr, Binder binder, Object[] parameters, CultureInfo culture)
at System.Delegate.DynamicInvokeImpl(Object[] args)
at System.Windows.Forms.Control.InvokeMarshaledCallbackDo(ThreadMethodEntry tme)
at System.Windows.Forms.Control.InvokeMarshaledCallbackHelper(Object obj)
at System.Threading.ExecutionContext.RunInternal(ExecutionContext executionContext, ContextCallback callback, Object state, Boolean preserveSyncCtx)
at System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state, Boolean preserveSyncCtx)
at System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state)
at System.Windows.Forms.Control.InvokeMarshaledCallback(ThreadMethodEntry tme)
at System.Windows.Forms.Control.InvokeMarshaledCallbacks()
at System.Windows.Forms.Control.WndProc(Message& m)
at MetroFramework.Controls.MetroUserControlBase.WndProc(Message& m) in f:\Users\DigitalJedi\Documents\Development\Projects\C#\Supporting Projects\MetroFramework-master\MetroFramework\Controls\MetroControlBase.cs:line 4129
另一个可能感兴趣的注意事项是:在捕获WndProc方法中生成的异常后,如果我允许程序继续执行,则此窗体和父级仍然名义上运行,并且不再遇到异常


希望有人能有点见识,我在胡说八道。先生们,干杯。

生成上述错误的调用发生在生成异常的线程之外的线程中;不管发布的调用堆栈是否准确

要确定哪个线程正在生成此问题,有必要在异常发生时检查所有正在运行的线程,并确定这些线程中是否有任何线程正在调用相关控件上的任何方法;在这种情况下也是如此


为了给这个问题提供一个清晰的答案,我将在“更好”的时间(可能是今晚)进一步扩展这个答案。

调用堆栈与您发布的代码片段没有任何关系。程序在错误的控件上崩溃。在代码中调用Begin/Invoke()时,没有传递正确的参数。调试+异常,勾选抛出复选框,使调试器在抛出异常时停止。Debug+Windows+线程,以查找包含错误调用的线程。按照您的指示,我在代码中的同一位置生成了完全相同的异常。具有相同的堆栈跟踪。如果您阅读了我的全部文章,我相信;我发布的堆栈跟踪是发生异常的线程中的堆栈跟踪;我已经发布了多个代码片段——一个启动有问题的线程的代码片段,以及围绕异常的代码片段。诊断调用中的bug不会有问题,使用Action代替Func得到的NRE很容易调试。您还没有找到最难的方法,这确实需要使用Thread debugger窗口来查找调用。请一位队友帮你解决这个问题。哈哈,你为什么要投反对票而不发表评论?就像一个蹒跚学步的孩子,毫无疑问是一个模拟西斯。当我看到类似的情况时,我想我应该让原力恢复平衡。