Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/274.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# Show和ShowDialog赢得';行不通_C#_.net_Multithreading_Winforms - Fatal编程技术网

C# Show和ShowDialog赢得';行不通

C# Show和ShowDialog赢得';行不通,c#,.net,multithreading,winforms,C#,.net,Multithreading,Winforms,这与我以前见过的任何东西都不一样。 当我调用(new System.Windows.Forms.Form()).ShowDialog()时,一个表单会显示一毫秒左右,然后消失。 我追踪了电话,得到了这个: System.Windows.Forms.Form.Dispose System.ComponentModel.Component.Dispose System.Windows.Forms.Application.ThreadWindows.Dispose System.Windows.For

这与我以前见过的任何东西都不一样。
当我调用(new System.Windows.Forms.Form()).ShowDialog()时,一个表单会显示一毫秒左右,然后消失。
我追踪了电话,得到了这个:

System.Windows.Forms.Form.Dispose
System.ComponentModel.Component.Dispose
System.Windows.Forms.Application.ThreadWindows.Dispose
System.Windows.Forms.Application.ThreadContext.DisposeThreadWindows
System.Windows.Forms.Application.ComponentManager.System.Windows.Forms.UnsafentiveMethods.IMsoComponentManager.FPushMessageLoop
System.Windows.Forms.Application.ThreadContext.RunMessageLoopInner
System.Windows.Forms.Application.ThreadContext.RunMessageLoop
System.Windows.Forms.Form.ShowDialog Esfand.Program.Main C#

我已经尝试了任何我想到的方法来解决这个问题

虽然我在尝试显示此表单之前已显示登录表单。
我不认为登录表单上有什么特别之处(通常很无聊,连接到服务器,发送凭证,接收数据)。
我正在使用窗体的主线程。我有消息和消息循环方面的经验。我在登录表单中使用了线程

编辑: 科迪·格雷建议的澄清:

这是我在
void Main(string[])
中看到的内容:

LoginForm login = new LoginForm ();
login.ShowDialog ();//works
if (login.DialogResult == DialogResult.OK)
{
    MainForm f = new MainForm ();
    f.ShowDialog ();//won't work
}
在新线程中创建并显示主窗体使一切重新开始工作。但每个窗体上都会出现随机错误,这使得此解决方案不够好

编辑2:
FormClosing事件甚至不会触发

System.Windows.Forms.Form A;
A = new Form();
A.FormClosing += new FormClosingEventHandler((sender, e) => { System.Diagnostics.Debugger.Break();/*won't work. tried Breakpoints and other stuff too*/ });
A.ShowDialog();
编辑3: HandleDestroyed事件堆栈跟踪:

>   Esfand.exe!Esfand.Program.Main.AnonymousMethod__1(object sender = {System.Windows.Forms.Form}, System.EventArgs e = {System.EventArgs}) Line 50 + 0x6 bytes C#
    System.Windows.Forms.dll!System.Windows.Forms.Control.OnHandleDestroyed(System.EventArgs e) + 0x9e bytes    
    System.Windows.Forms.dll!System.Windows.Forms.Form.OnHandleDestroyed(System.EventArgs e) + 0x13 bytes   
    System.Windows.Forms.dll!System.Windows.Forms.Control.WmDestroy(ref System.Windows.Forms.Message m) + 0x54 bytes    
    System.Windows.Forms.dll!System.Windows.Forms.Control.WndProc(ref System.Windows.Forms.Message m) + 0x547 bytes 
    System.Windows.Forms.dll!System.Windows.Forms.Form.WndProc(ref System.Windows.Forms.Message m) + 0x6d bytes 
    System.Windows.Forms.dll!System.Windows.Forms.NativeWindow.DebuggableCallback(System.IntPtr hWnd, int msg = 2, System.IntPtr wparam, System.IntPtr lparam) + 0x15e bytes    
    [Native to Managed Transition]  
    [Managed to Native Transition]  
    System.Windows.Forms.dll!System.Windows.Forms.NativeWindow.DestroyHandle() + 0xf7 bytes 
    System.Windows.Forms.dll!System.Windows.Forms.Control.DestroyHandle() + 0x3e3 bytes 
    System.Windows.Forms.dll!System.Windows.Forms.Control.Dispose(bool disposing) + 0x347 bytes 
    System.Windows.Forms.dll!System.Windows.Forms.ContainerControl.Dispose(bool disposing) + 0x19 bytes 
    System.Windows.Forms.dll!System.Windows.Forms.Form.Dispose(bool disposing) + 0x26a bytes    
    System.dll!System.ComponentModel.Component.Dispose() + 0x1b bytes   
    System.Windows.Forms.dll!System.Windows.Forms.Application.ThreadWindows.Dispose() + 0xb3 bytes  
    System.Windows.Forms.dll!System.Windows.Forms.Application.ThreadContext.DisposeThreadWindows() + 0x12d bytes    
    System.Windows.Forms.dll!System.Windows.Forms.Application.ComponentManager.System.Windows.Forms.UnsafeNativeMethods.IMsoComponentManager.FPushMessageLoop(System.IntPtr dwComponentID, int reason, int pvLoopData) + 0x58e bytes    
    System.Windows.Forms.dll!System.Windows.Forms.Application.ThreadContext.RunMessageLoopInner(int reason = 4, System.Windows.Forms.ApplicationContext context = {System.Windows.Forms.Application.ModalApplicationContext}) + 0x593 bytes 
    System.Windows.Forms.dll!System.Windows.Forms.Application.ThreadContext.RunMessageLoop(int reason, System.Windows.Forms.ApplicationContext context) + 0x81 bytes    
    System.Windows.Forms.dll!System.Windows.Forms.Form.ShowDialog(System.Windows.Forms.IWin32Window owner) + 0x765 bytes    
    Esfand.exe!Esfand.Program.Main(string[] a = {string[0]}) Line 51 + 0x10 bytes   C#

尝试检查是否引发线程异常错误。检查是否在应用程序线程异常事件中看到任何内容

static void Main()
{
    Application.ThreadException += new System.Threading.ThreadExceptionEventHandler(Application_ThreadException);
    try
    {
        //Your existing code
    }
    catch (Exception ex)
    {
    }
}

private static void Application_ThreadException(object sender, System.Threading.ThreadExceptionEventArgs e)
{
}
编辑: 另一个选项是显式地将MainForm设置为正在创建的新表单的所有者

newForm.ShowDialog(MainForm);
我有一种感觉,在默认情况下,所有者被设置为您的登录表单,该表单已关闭,这将自动关闭您的新表单

这使得程序中的每一个表单都会引发一个唯一的错误(例如,`无法注册拖放事件处理程序')

这是对代码中核心问题的强烈暗示。当您有AllowDrop属性设置为true的任何控件时,将调用RegisterDragDrop()本机函数。在创建窗体的本机窗口时调用它。不幸的是,如果您有64位版本的Windows,并且您强制程序以32位模式运行,那么此时引发任何异常都是非常糟糕的。研究的主题

RegisterDragDrop()失败的原因很少。只有一个。我们已经可以从您的代码片段中看出,您一直在修补Program.cs。它的样板版本如下所示:

static class Program {
    /// <summary>
    /// The main entry point for the application.
    /// </summary>
    [STAThread]                // <=== Here!!!
    static void Main() {
        Application.EnableVisualStyles();
        Application.SetCompatibleTextRenderingDefault(false);
        Application.Run(new Form1());
    }
}
静态类程序{
/// 
///应用程序的主要入口点。
/// 

[STAThread]/事件队列上有WM\U QUIT消息时,IMsoComponentManager.FPushMessageLoopP()
将调用
Application.ThreadContext.DisposeThreadWindows()


您是否在
LoginForm
的按钮事件处理程序中发布退出消息?

尝试将表单定义为类成员。而不是在函数中。

您的
Main
方法看起来很奇怪。我认为您缺少对
应用程序的调用。Run()
。由于您不希望应用程序在登录表单关闭后立即退出,因此可能需要一个
ApplicationContext
。MSDN有一个示例:


另一种可能性是调用
Application.Run()
,使用一个不可见的表单作为参数,然后显示其他表单(并且在应用程序退出之前永远不会关闭),但我认为这是一个相当丑陋的黑客行为。

我的理解是表单需要在应用程序上下文中运行

我继承了一些代码,这些代码以以下方式从主上下文启动多个表单:

var form1 = Form1();
Application.Run(form1);

// form returns, check public method form.ButtonPushed etc
if (form.Button1Pushed)
{
    var form2 = Form2();
    Application.Run(form2);
}
这将成功地推出多种形式


这感觉不是一种非常优雅的方式,但它很有效…

尝试在对话框中设置断点,我猜它会抛出和例外。因此,确保在主线程上执行时创建并显示对话框。当您尝试从后台线程创建或显示UI表单时,会发生不好的情况。您是否尝试创建obj
form
的ect,然后调用它???@dthorpe我正在为此使用主线程,我确信这一点。为FormClosing事件添加一个事件处理程序,并在其上设置一个断点。查看调用堆栈。+1,不知道那个调用堆栈。希望它能工作,但什么也没发生。您能将调用更改为类似于
DialogResult DialogResult的内容吗t=(new System.Windows.Forms.Form()).ShowDialog();
并检查dialogResult中的值。另一个选项是将所有者表单设置为MainForm,如
newForm.ShowDialog(MainForm)
我将两种方式都尝试,每次登录都需要几分钟,因为登录时间太长。对话框结果是Cancel=2,另一个我无法执行,因为我们正在讨论的表单是主表单。+1,我很快会检查这一点。我刚刚失去了对上游代码的访问权限几天。嗯,我无法再解释为什么要注册gDrop()将失败,对您的执行环境了解不够,我看不到您的Main()方法或登录表单。否则,它会解释您看到的所有内容,因此请验证您的假设。添加一行调用System.Threading.Thread.CurrentThread.GetApartmentState()的代码如果你在LogNebug中使用任何ActiveX组件,那么考虑它有bug的可能性,并调用CONPRORIALIZE(),这也会是致命的。我没有使用任何外部库或ActiveX组件。这很难帮助用户一次只提供一点信息。您需要正确记录您的pr
var form1 = Form1();
Application.Run(form1);

// form returns, check public method form.ButtonPushed etc
if (form.Button1Pushed)
{
    var form2 = Form2();
    Application.Run(form2);
}