1

したがって、私の問題は、wpfアプリケーションにエンドレススレッドを設定すると、UIがハングすることですが、もちろん、これはマルチスレッドアプリケーションに期待するものではありません。

ここに私のコードがあります

public partial class MainWindow : Window
{
    public MainWindow()
    {
        InitializeComponent();
        System.Threading.Thread thread = new System.Threading.Thread(
            new System.Threading.ThreadStart(
                delegate
                {
                    Dispatcher.Invoke(DispatcherPriority.Normal,
                        new Action<Polyline>(ChangePoints), polyline);
                }));
        thread.Start();
    }

    private void ChangePoints(Polyline p)
    {
        while (true)
        {
            Random random = new Random();
            p.Points.Clear();
            for (int i = 0; i < 500; i += 10)
            {
                p.Points.Add(new Point(i, random.Next(1, 300)));
            }
        }
    }
}


<Window x:Class="ClientSide.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        Title="MainWindow" Height="300" Width="500">
    <Canvas x:Name="canvas" Background="#00FFFFFF">
        <Polyline x:Name="polyline" Stroke="DarkGreen" StrokeThickness="3" />
    </Canvas>
</Window>

ここで何が悪いのか教えてもらえますか?

4

1 に答える 1

4

ここで何が悪いのか教えてもらえますか?

新しいスレッドを作成しますが、すぐにDispatcherを使用して、スレッドの作業をUIスレッドにマーシャリングします。これにより、UIスレッドで完全に実行されます。

無限ループを実行しているため、UIスレッドが無期限にロックされます。

修正するには、ロジックを切り替える必要があります。メソッド全体のUIスレッドにコールバックをマーシャリングするのではなく、代わりにポイントを構築しp.Points、ループ内で設定したコールのみをマーシャリングします。また、(現在のコードを前提として)可能な限り高速に実行されるため、UIが応答しなくなる可能性があるため、そこに何らかの形式の遅延を作成する必要がある場合があります。

次のようなものを試してください。

public MainWindow()
{
    InitializeComponent();
    System.Threading.Thread thread = new System.Threading.Thread(
        new Action(() => ChangePoints(polyline)));
    thread.Start();
}

private void ChangePoints(Polyline p)
{
    // Create once and reuse
    Random random = new Random();

    while (true)
    {
        PointCollection points = new PointCollection();
        for (int i = 0; i < 500; i += 10)
        {
            points.Add(new Point(i, random.Next(1, 300)));
        }

        // Now marshal back to the UI thread here...
        Dispatcher.Invoke(DispatcherPriority.Normal, 
            new Action( () => p.Points = points));

        // Optionally delay a bit here...
        Thread.Sleep(250);
    }
}
于 2012-10-01T17:44:54.093 に答える