2012-10-01 52 views
1

所以我的问题是,当我为我的wpf应用程序设置无尽的线程时,ui挂起,但当然这不是我期望从多线程应用程序中获得的。当试图运行无限循环线程时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

can you guys tell me whats wrong in here?

您创建一个新线程,但立即使用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); 
    } 
} 
+0

感谢很多人,但我想你的代码只有在你输入“新的行动(()=> ChangePoints(折线)));”一个微小的变化我必须将其更改为“新的ThreaStart(()=> ChangePoints(polyline)));”并得到一个运行时异常:调用线程不能访问此对象,因为不同的线程拥有它。 –

+0

@SlavaZoref你从哪里得到这个错误? –

+0

启动应用程序后出现错误。但是,不幸的是,确切位置没有显示。 –