私はC#WPFプロジェクトが比較的新しく、タスクを実行している間にユーザーインターフェイスが「ロックアップ」するというコードに問題があります。ここに関連するコードです:ここではManagedDLA2DContainer
WPFでGUIがハングするのを防ぐ
public partial class MainWindow : Window {
// handles to ManagedDLAContainer objects
private ManagedDLA2DContainer dla_2d;
public MainWindow() {
InitializeComponent();
// initalise aggregate containers
dla_2d = new ManagedDLA2DContainer();
}
private void GenerateAggregate() {
// generate the 2D aggregate of size given by particles_slider value
Dispatcher.Invoke(new Action(() => { dla_2d.Generate((uint)particles_slider.Value); }));
// TODO: add particles to "canvas" on GUI as they are generated
}
private void GenerateButtonClick(object sender, RoutedEventArgs e) {
// set the coefficient of stickiness of aggregate
// to current value of stickiness_slider
dla_2d.SetCoeffStick(stickiness_slider.Value);
// start asynchronous task calling GenerateAggregate method
Task.Factory.StartNew(() => GenerateAggregate());
}
}
は、いくつかのネイティブ、アンマネージドコードC++
とstickiness_slider
のマネージC++/CLI
ラッパーが単にWPFインターフェイスのSlider
要素です。同様に、particles_slider
はインタフェースの別のSlider要素です。
public partial class MainWindow : Window {
// lock object for multi-threading tasks
private static readonly object locker = new object();
// handles to ManagedDLAContainer objects
private ManagedDLA2DContainer dla_2d;
public MainWindow() {
InitializeComponent();
// initalise aggregate containers
dla_2d = new ManagedDLA2DContainer();
}
private void GenerateAggregate() {
// lock around aggregate generation
lock (locker) {
// generate the 2D aggregate of size given by particles_slider value
Dispatcher.Invoke(new Action(() => { dla_2d.Generate((uint)particles_slider.Value); }));
// TODO: add particles to "canvas" on GUI as they are generated
}
}
private void GenerateButtonClick(object sender, RoutedEventArgs e) {
// set the coefficient of stickiness of aggregate
// to current value of stickiness_slider
dla_2d.SetCoeffStick(stickiness_slider.Value);
Thread agg_gen_thread = new Thread(GenerateAggregate);
agg_gen_thread.Start();
agg_gen_thread.Join();
}
}
私はここで間違っているかもしれないもの理解するのに役立つ可能性のある情報が高く評価されています。私は、次のコードはまた、GUIがハングにつながることに注意してください。あなたが興味がある場合
はまた、このプロジェクトのすべてのコードはここにあります:https://github.com/SJR276/DLAProject
'Dispatcher.Invoke'を指定しないと、別のスレッドがそのオブジェクトを所有しているため、呼び出し側スレッドがこのオブジェクトにアクセスできないという実行時例外が発生します。また、 'GenerateAggregate'はGUIにアイテムを追加するので(最終的に)、' Dispatch.Invoke'を使う必要があると私は理解しています。 – ArchbishopOfBanterbury
メソッド全体ではなく、UIコントロールを更新する_only_パーツをディスパッチする必要があります。 – Evk
ああ、わかりました。私は注意すべきです - 'Generate'はC++/CLIコードである' ManagedDLA2DContainer'クラスのメソッドです。実際にC++/CLIラッパーからUIを更新することは可能ですか? – ArchbishopOfBanterbury