使用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);
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。
应用程序顶部表单。///可以为空,如果未知的