0

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);
4

2 に答える 2

1

この場合、Control.Invoke は実際に必要ですか?

通常は UI スレッドですが、そうである必要はないコントロールを作成するスレッドが UI 要素に確実にアクセスできるようにするために、invoke が使用されているという印象を常に受け​​ていました。

この場合、スレッドからダイアログを作成しようとしているように見えるため、スレッドからダイアログを更新できるはずです。(明らかに、メイン UI スレッドを含むスレッドの外部からアクセスすることはできません)。

私が間違っていれば、これはすぐに反対票を投じられることは間違いありません。

于 2011-07-18T14:14:04.423 に答える
0

mParentControl は、正しくないように見える NULL の場合でも、常に parentControl と同じに設定されます。

プログラムが応答しなくなる理由は、mParentControl が NULL であるためです。

DialogResult result = dialog.ShowDialog(mParentControl);

この問題の解決策の 1 つは、親がわかっている場合にのみダイアログを表示することです。

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

私は次のコードに基づいて答えました:

 if (parentControl != null)
                { 
                   mInvokeControl = parentControl;                
                }       

私の答えは意味がないと言っていると思います。Hans Passant のコメントが真実を保持していないか、コードが実際には正しく、バグを発見したことは、より理にかなっています。あなたは失礼なので、私は自分の経験を生かして他の誰かを助けます. mParentControl is Null の状況が発生する可能性があるため、ユーモアを交えてコードを追加してください。mParentControl は、NULL の場合でも常に parentcontrol に設定されます。

アプリケーショントップフォーム。/// 不明な場合は null になる可能性があります

于 2011-07-18T17:37:47.413 に答える