0

悪い質問かもしれませんが、いくつかのコマンドをサーバーに送信するクライアント アプリがあります。コマンドを送信するための小さな関数を作成しました。これは、メッセージが受信されるまで単純に待機しAutoResetEvent.WaitOne()、メッセージを文字列として返します。この関数は、sth を実装するための高速な方法だったので、クライアント アプリで頻繁に使用しました。

サーバーからの応答を待っている間、このアプリで LoadingCircle を表示したいと思います。そのための sth をメッセージ受信関数で既に作成しました。これは単にフォームにコントロールを追加するだけです。これは機能していますが、数ミリ秒後に再描画される UserControl(Loading Circle) は再描画されません。AutoResetEvent.WaitOne()GUIスレッドをブロックしています。メッセージ受信部分を別のスレッドに移動できることはわかっていますが、 150x以上のメッセージ受信関数を使用したため、この関数の概念を変更したくありません。

だから私の質問は次のとおりです。待機中にGUIイベントを実行するための怠惰な方法はありますか、それともLoadingCircleコントロールの描画部分を別のスレッドに移動できますか?

どんな助けでも大歓迎です

4

2 に答える 2

2

基本的に非同期操作を実行し、を介して同期操作に変換しましたAutoResetEvent.WaitOne。そして今、あなたはそれを非同期操作に戻したいと思います。

私の提案は、関数をUIから分離することです。次に、同期オプションと非同期オプションをツールします。そうすることで、完全に機能するアプリを維持し、変更が必要な150個のインスタンスのコードの再書き込み中に段階的にリリースできます。

4.5の新しいasyncおよびawaitキーワードは、ここでうまく機能するはずです。

于 2013-01-25T19:58:34.307 に答える
-2

ここで小さな修正を見つけました 、うまく機能します(私はそれを信用できません)

private static TimeSpan InfiniteTimeout = TimeSpan.FromMilliseconds(-1); 
private const Int32 MAX_WAIT = 100; 

public static bool Wait(WaitHandle handle, TimeSpan timeout) 
{ 
    Int32 expireTicks; 
    bool signaled; 
    Int32 waitTime; 
    bool exitLoop; 

    // guard the inputs 
    if (handle == null) { 
        throw new ArgumentNullException("handle"); 
    } 
    else if ((handle.SafeWaitHandle.IsClosed)) { 
        throw new ArgumentException("closed wait handle", "handle"); 
    } 
    else if ((handle.SafeWaitHandle.IsInvalid)) { 
        throw new ArgumentException("invalid wait handle", "handle"); 
    } 
    else if ((timeout < InfiniteTimeout)) { 
        throw new ArgumentException("invalid timeout <-1", "timeout"); 
    } 

    // wait for the signal 
    expireTicks = (int)Environment.TickCount + timeout.TotalMilliseconds; 
    do { 
        if (timeout.Equals(InfiniteTimeout)) { 
            waitTime = MAX_WAIT; 
        } 
        else { 
            waitTime = (expireTicks - Environment.TickCount); 
            if (waitTime <= 0) { 
                exitLoop = true; 
                waitTime = 0; 
            } 
            else if (waitTime > MAX_WAIT) { 
                waitTime = MAX_WAIT; 
            } 
        } 

        if ((handle.SafeWaitHandle.IsClosed)) { 
            exitLoop = true; 
        } 
        else if (handle.WaitOne(waitTime, false)) { 
            exitLoop = true; 
            signaled = true; 
        } 
        else { 
            if (Application.MessageLoop) { 
                Application.DoEvents(); 
            } 
            else { 
                Thread.Sleep(1); 
            } 
        } 
    } 
    while (!exitLoop); 

    return signaled;
}
于 2013-01-26T10:43:06.823 に答える