使用invoke的ShowDialog使应用程序无响应

本文关键字:应用程序 响应 ShowDialog invoke 使用 | 更新日期: 2023-09-27 18:02:18

我使用Control.Invoke()来显示一个对话框。代码是一个从用户获取凭证的处理程序,它可以在线程中执行,这就是我将调用执行到InvokeRequired/Invoke片段中的原因。

有时,只有在某些机器上,当我关闭对话框时,应用程序变得无响应(它不管理一些鼠标点击,但管理其他鼠标点击)。如果我执行一些"允许的"操作,应用程序将再次开始响应。似乎处理任何事件,应用程序都会自行修复。

你知道。net框架中任何已知的bug,或者可能导致这个问题的东西吗?

提前感谢。


EDIT:这是我使用的代码:

public class GuiCredentialsHandler
{
    // control used to invoke if needed
    private static Control mInvokeControl;
    // control used as parent for showDialog (could be null)
    private static Control mParentControl;
    /// <summary>
    /// Initialize a GetCredentials handler for current process.
    /// This method should be always called from the UI thread, for
    /// a correctly handling for invokes (when the handler is called
    /// from a thread).
    /// </summary>
    /// <param name="parentControl">Application top form. 
    /// Can be null if unknown</param>
    public static void Initialize(Control parentControl)
    {
        if (parentControl != null)
        {
            mInvokeControl = parentControl;
        }
        else
        {
            mInvokeControl = new Control();
            // force to create window handle
            // otherwise, invoke required always
            // return false
            mInvokeControl.CreateControl();
        }
        mParentControl = parentControl;
    }
    public static Credentials GetCredentials(
        string servername, SEIDWorkingMode serverWorkingMode)
    {
        if (mInvokeControl.InvokeRequired)
        {
            return mInvokeControl.Invoke(
                new GetCredentialsDelegate(DoGetCredentials),
                new object[] { servername, serverWorkingMode })
            as Credentials;
        }
        else
        {
            return DoGetCredentials(servername, serverWorkingMode);
        }
    }
    private static Credentials DoGetCredentials(
        string servername, SEIDWorkingMode serverWorkingMode)
    {
        GetCredentialsDialog dialog = new GetCredentialsDialog();
        dialog.Server = servername;
        dialog.WorkingMode = serverWorkingMode;
        DialogResult result = dialog.ShowDialog(mParentControl);
        if (result == DialogResult.Cancel) return null;
        UserInfoRetriever retriever = new UserInfoRetriever(
            servername, serverWorkingMode,
            dialog.UserName, dialog.Password);
        SEID seid = retriever.GetCurrentUser();
        return new Credentials(seid, serverWorkingMode);
}
public delegate Credentials GetCredentialsDelegate(
    string serverName,
    SEIDWorkingMode mode);

使用invoke的ShowDialog使应用程序无响应

Is Control。在这种情况下实际需要调用?

我一直有这样的印象,调用是用来确保UI元素被创建的线程访问的,通常是UI线程,但不一定是。

在这种情况下,它看起来像你试图从一个线程创建一个对话框,因此你应该能够从线程更新它。(显然你不能从你的线程之外访问它,这将包括主UI线程)。

如果我错了,毫无疑问这篇文章很快就会被否决。

mParentControl将始终被设置为等于parentControl,即使它是NULL,这似乎是不对的。

程序变得无响应的原因是你的mParentControl为NULL:

DialogResult result = dialog.ShowDialog(mParentControl);

解决这个问题的一个方法是只在父节点已知的情况下显示对话框。

if ( mParentControl != NULL )
    DialogResult result = dialog.ShowDialog(mParentControl);
else
    DialogResult result = dialog.ShowDialog(mInvokeControl);

我的答案基于以下代码:

 if (parentControl != null)
                { 
                   mInvokeControl = parentControl;                
                }       
我想你的意思是我的回答没有意义。更有意义的是,汉斯·帕桑特的注释不符合某些事实,或者你的代码实际上是正确的,而你发现了一个bug。既然你这么无礼,我就拿我的经验去帮助别人吧。幽默地添加代码来避免mParentControl是Null的情况,因为它可能发生。mParentControl总是被设置为parentcontrol,即使它是NULL。

应用程序顶部表单。///可以为空,如果未知的