WPFで多数のUI要素を逆シリアル化しているときにUIがフリーズしないようにするにはどうすればよいですか?別のスレッドでそれらをロードしようとしているときに、オブジェクトがUIスレッドに属しているというエラーが表示されます。だから、私はUIデータをロードしている間、Vistaの「プログラムが応答しない」というエラーを防ぐためにどのようなオプションが必要ですか?私は単一スレッドのソリューションに頼ることができますか、おそらく複数のUIスレッドに関する何かを見逃していますか?追加のスレッドなしでUIがフリーズするのを防ぐ
答えて
スレッドを1つだけ使用している場合は、処理量は増えますが、UIはフリーズします。
BackgroundWorkerスレッドを使用すると、発生するタイミングをより詳細に制御できます。&
UIを更新するには、バックグラウンドスレッドのDispatcher.Invoke
を使用して、スレッドの境界を越えて呼び出しをマーシャリングする必要があります。
あなたはまだ別のスレッドで、あなたの長い処理を行うことができますが、終了したら、あなたはOldNewThingのブログからDispatcher.BeginInvoke(your_UI_action_here)
勧告を呼び出すことによって、UIスレッドと同期する必要があります。
スレッドルートを使用して1つのGUIスレッドを作成し、終了したメインGUIスレッドにレポートを戻す別のスレッドにワークロードを送り出すことが最適です。これは、GUIインターフェイスでスレッドの問題に陥ることがないためです。
だから1つのGUIスレッド 作業を行う多くのワーカースレッド。
スレッドのいずれかがハングした場合、ユーザーはアプリケーションを直接制御でき、アプリケーションインターフェイスでの経験をしなくてもスレッドを閉じることができます。これは彼が喜んであなたのユーザーは彼が常に停止ボタンをクリックして停止をクリックして検索以外のコントロールを感じるので、幸せになります。
お試しくださいfreezingあなたのUIElements。凍ったオブジェクトは、InvalidOperationExceptionが発生することなくスレッド間で渡すことができるため、UIスレッドで使用する前に、&をバックグラウンドスレッドでフリーズします。
また、個々のデシリアライズをバックグラウンド優先度でUIスレッドに戻すことを検討してください。これは最適ではありません。なぜなら、UIスレッドはこれらのオブジェクトを逆シリアル化する作業をすべて実行しなければならず、個々のタスクとしてそれらをディスパッチすることによっていくつかのオーバーヘッドが追加されますが、少なくともUIをブロックしません優先順位の低いデシリアライゼーション作業に混乱する可能性があります。
これはフリーズ可能ですが、UI要素はフリーズできません。したがって、ジオメトリやブラシなどを作成することについて話しているだけですが、UI要素(ビジュアルクラスや継承チェーン)を構築することについて話しているのであれば、そうではありません。 –
UIElementのポイントがフリーズできません。 –
Here is a wonderful blog posting from Dwane Needは、複数のスレッド間でUI要素を操作するためのすべての利用可能なオプションについて説明しています。
あなたは本当に良い処方箋を与えるために十分な詳細を与えていません。たとえば、データバインディングを使用する代わりに、自分でUI要素を作成するのはなぜですか?正当な理由があるかもしれませんが、詳細がなくても良いアドバイスをするのは難しいです。有用と思われる詳細の別の例として、データの各部分に対して深くネストされた複雑なコントロール階層を構築しようとしているのか、単純な形状を描くだけでよいのでしょうか?
DispatcherFramesを使用して、コントロールのフローをそのヘッドでオンにすることで、バックグラウンドでUIスレッドでデシリアライズを続行できます。
まず、逆シリアル化中に定期的に制御を取得する方法が必要です。どのデシリアライザを使用していても、オブジェクトのプロパティセットを呼び出す必要があるため、通常はプロパティセッターにコードを追加できます。あるいは、デシリアライザを変更することもできます。いずれにせよ、あなたのコードは、あなたがコントロールを受ける
たびに十分な頻度と呼ばれていることを確認し、すべてを行う必要がある:
- DispatcherFrame
- キューBeginInvokeメソッドを使用してディスパッチャにイベントを作成することデシリアライザを呼び出すときにセットがディスパッチャ上で実行されているフレームを開始するには、フレーム
- 利用PushFrame上= falseを続行
また、自身が必ずヨーヨーを作ります)DoEvents関数でDateTime.Nowをチェック
public partial class MyWindow
{
SomeDeserializer _deserializer = new SomeDeserializer();
byte[] _sourceData;
object _deserializedObject;
...
void LoadButton_Click(...)
{
Dispatcher.BeginInvoke(DispatcherPriority.Background, new Action(() =>
{
_deserializedObject = _deserializer.DeserializeObject(_sourceData);
}));
}
}
public class OneOfTheObjectsBeingDeserializedFrequently
{
...
public string SomePropertyThatIsFrequentlySet
{
get { ... }
set { ...; BackgroundThreadingSolution.DoEvents(); }
}
}
public class BackgroundThreadingSolution
{
[ThreadLocal]
static DateTime _nextDispatchTime;
public static void DoEvents()
{
// Limit dispatcher queue running to once every 200ms
var now = DateTime.Now;
if(now < _nextDispatchTime) return;
_nextDispatchTime = now.AddMilliseconds(200);
// Run the dispatcher for everything over background priority
var frame = new DispatcherFrame();
Dispatcher.CurrentDispatcher.BeginInvoke(DispatcherPriority.Background, new Action(() =>
{
frame.Continue = false;
}));
Dispatcher.PushFrame(frame);
}
}
を(実際にはありません:など
uはDispatcher.BeginInvokeからそれを行う、またはあなたの呼び出し元のコードは、すべてのロックを保持していないことをここではそれがどのように見えるかですこの技法には必要ですが、非直列化中にSomePropertyが頻繁に設定されているとパフォーマンスが向上します。
編集:私はこれを書いた直後に、DoEventsメソッドを実装する簡単な方法があることを認識しました。 DispatcherFrameを使用する代わりに、単に空のアクションでDispatcher.Invokeを使用してください。
public static void DoEvents()
{
// Limit dispatcher queue running to once every 200ms
var now = DateTime.Now;
if(now < _nextDispatchTime) return;
_nextDispatchTime = now.AddMilliseconds(200);
// Run the dispatcher for everything over background priority
Dispatcher.CurrentDispatcher.Invoke(DispatcherPriority.Background, new Action(() => {}));
}
私のパネルで項目を移動しているのと同様の問題がありました。優先度がLoadedのDispatcherTimerを使用していたため、UIがフリーズしていました。 DispatcherPriority.Inputに変更するとすぐに問題は解決しました。
- 1. フォームがフリーズするのを防ぐ
- 2. ページがフリーズするのを防ぐ
- 3. Tkinter:スレッドを使用してメインイベントループが「フリーズ」するのを防ぐ方法
- 4. スレッドがフリーズするUI - Android
- 5. UIスレッドがフリーズする複数のレルムトランザクション
- 6. Timer1はUIスレッドをフリーズします
- 7. lxmlがデフォルトのdoctypeを追加するのを防ぐ方法
- 8. スレッドではUIがフリーズモードでのみフリーズしています
- 9. andengine:updatethreadの呼び出しがuiスレッド/アニメーションをフリーズする
- 10. anglejsがフォームにクラスを追加するのを防ぐ
- 11. テーブルが行以上を追加するのを防ぐ
- 12. 反応ルータがURLを#追加するのを防ぐには?
- 13. 多くのスレッドをPlatform.runLater()で使用してフリーズするJavaFX UI
- 14. Tkinterスレッドが原因でUIがフリーズする
- 15. tinymceが余分な空白行を追加するのを防ぐ方法
- 16. UIは別のスレッドでもプロセスをフリーズしますか?
- 17. ロード中にフリーズするのを防ぐ方法google map
- 18. 関連するコアデータオブジェクトをバックグラウンドで取得しますか? (UIフリーズを防ぐため)
- 19. jQuery:( 'クリック')を2回追加するのを防ぐ
- 20. tkinterボタンGUIをフリーズするのを防ぐためにスレッドを開始するには
- 21. 新しいノードの追加時にノードのオーバーラップを防ぐ
- 22. HibernateがMySQLでユーザ名にホスト名を追加するのを防ぐ方法
- 23. jQuery UI - Shakeエフェクトが複数回発生するのを防ぐ
- 24. フリーズされたアプリケーションを防ぐためにファイルをコピーする
- 25. テーブルビューでUIがフリーズする
- 26. 複雑なWPF UIの再構築時のフリーズを防止しますか?
- 27. EasyPHP DevServer 16がエイリアスのプレフィックス 'edsa'を追加するのを防ぐ方法
- 28. Firefoxがcontentノードにdivを追加するのを防ぐ(Firefoxのバグ?)
- 29. Pythonスレッドを閉じてメモリリークを防ぐ
- 30. 追加されたイベントハンドルによるメモリリークを防ぐための予防策
Windowsフォームでは、Application.DoEvents()を使用できます。私はそれがWPFで動作するかわからない。 – Qwertie