悪い質問かもしれませんが、いくつかのコマンドをサーバーに送信するクライアント アプリがあります。コマンドを送信するための小さな関数を作成しました。これは、メッセージが受信されるまで単純に待機しAutoResetEvent.WaitOne()
、メッセージを文字列として返します。この関数は、sth を実装するための高速な方法だったので、クライアント アプリで頻繁に使用しました。
サーバーからの応答を待っている間、このアプリで LoadingCircle を表示したいと思います。そのための sth をメッセージ受信関数で既に作成しました。これは単にフォームにコントロールを追加するだけです。これは機能していますが、数ミリ秒後に再描画される UserControl(Loading Circle) は再描画されません。AutoResetEvent.WaitOne()
GUIスレッドをブロックしています。メッセージ受信部分を別のスレッドに移動できることはわかっていますが、 150x以上のメッセージ受信関数を使用したため、この関数の概念を変更したくありません。
だから私の質問は次のとおりです。待機中にGUIイベントを実行するための怠惰な方法はありますか、それともLoadingCircleコントロールの描画部分を別のスレッドに移動できますか?
どんな助けでも大歓迎です
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 に答える