我正在使用Control.Invoke()
来显示对话框。代码是从用户获取凭据的处理程序,它可以在线程中执行,这就是我将调用执行到InvokeRequired/Invoke
代码段的原因。
有时候,只有在某些机器中,当我关闭对话框时,应用程序才会变得无法控制(它不会管理一些鼠标点击,而是管理其他鼠标)。如果我执行一些“允许”操作,应用程序将再次开始响应。似乎处理任何事件,应用程序自行修复。
你知道.NET框架中的任何已知错误,还是可能导致此问题的错误?
提前致谢。
编辑:这是我正在使用的代码:
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);
答案 0 :(得分:1)
在这种情况下,实际上是否需要Control.Invoke?
我总是认为invoke用于确保UI元素由创建控件的线程访问,该控件通常是UI线程,但不一定是。
在这种情况下,您似乎正在尝试从线程创建对话框,因此您应该能够从线程更新它。 (显然你不能从你的线程外部访问它,它将包括主UI线程)。
如果我错了,毫无疑问,这将很快得到落实。
答案 1 :(得分:0)
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;
}
我认为你的意思是我的回答毫无意义。更有意义的是,汉斯帕斯特的评论没有说实话,或者你的代码实际上是正确的,你发现了一个错误。既然你很粗鲁,我会接受我的经验并帮助别人。幽默自己并添加代码以避免mParentControl处于空状态,因为它可能会发生。 mParentControl总是设置为parentcontrol,即使它是NULL。
申请表格。 ///如果是,可以为null 未知