2013-08-04 61 views
1

我是新来的.NET ,我想一个窗口上应用两个线程多线程在一个WPF窗口

应用程序包含两个按钮(启动和停止)和一个只读文本框 当用户点击开始程序将从COM端口读取并将其附加到文本框,当点击停止它将停止。 的问题是每当我点击启动程序卡住

只把它缩短在这里,我使用的“Hello World!”。

C#代码:

using System; 
using System.Windows; 
using System.Threading; 

namespace ThreadingTest 
{ 
/// <summary> 
/// Interaction logic for MainWindow.xaml 
/// </summary> 
public partial class MainWindow : Window 
{ 
    private bool _continue = false; 

    public MainWindow() 
    { 
     InitializeComponent(); 
    } 

    private void startWrite(object sender, RoutedEventArgs e) 
    { 
     startButton.IsEnabled = false; 
     stopButton.IsEnabled = true; 
     _continue = true; 
     Dispatcher.Invoke((Action)(() => 
     { 
      Hello(); 
     })); 
    } 

    private void stopWrite(object sender, RoutedEventArgs e) 
    { 
     startButton.IsEnabled = true; 
     stopButton.IsEnabled = false; 
     _continue = false; 
    } 

    public void Hello() 
    { 
     while (_continue) 
     { 
      HelloText.AppendText("Hello World!\n"); 
      //_continue = false; 
     } 
    } 
} 
} 

XAML代码:

<Window x:Class="ThreadingTest.MainWindow" 
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
    Title="MainWindow" Height="296" Width="301" 
    Background="WhiteSmoke"> 
<Grid> 
    <Grid.RowDefinitions> 
     <RowDefinition Height="245*" /> 
     <RowDefinition Height="12*" /> 
    </Grid.RowDefinitions> 
    <TextBox Name="HelloText" 
      IsReadOnly="True" 
      HorizontalAlignment="Left" 
      Margin="12,12,0,0" 
      VerticalAlignment="Top" 
      Height="233" 
      Width="174" /> 
    <Button Name="startButton" 
      IsEnabled="True" 
      HorizontalAlignment="Left" 
      VerticalAlignment="Top" 
      Height="25" 
      Width="50" 
      Margin="208,12,0,0" 
      Content="Start" 
      Click="startWrite" /> 
    <Button Name="stopButton" 
      IsEnabled="False" 
      HorizontalAlignment="Left" 
      VerticalAlignment="Top" 
      Height="25" 
      Width="50" 
      Margin="208,45,0,0" 
      Content="Stop" 
      Click="stopWrite" /> 
</Grid> 
</Window> 

和对不起我的英语

回答

1

您应该使用BackgroundWorker(msdn)。

实施例:

public partial class MainWindow : Window 
{ 
    private bool _continue = false; 

    public MainWindow() 
    { 
     InitializeComponent(); 

     worker.WorkerSupportsCancellation = true; 
     worker.DoWork += delegate 
     { 
      Hello(); 
     }; 
    } 

    BackgroundWorker worker = new BackgroundWorker(); 

    private void startWrite(object sender, RoutedEventArgs e) 
    { 
     startButton.IsEnabled = false; 
     stopButton.IsEnabled = true; 
     _continue = true; 
     worker.RunWorkerAsync(); 
    } 

    private void stopWrite(object sender, RoutedEventArgs e) 
    { 
     worker.CancelAsync(); 
     startButton.IsEnabled = true; 
     stopButton.IsEnabled = false; 
     _continue = false; 
    } 

    public void Hello() 
    { 
     while (_continue) 
     { 
      Application.Current.Dispatcher.Invoke((Action)(() => 
      { 
       HelloText.AppendText("Hello World!\n"); 
      }));     
     } 
    } 
} 
+0

几乎可以完美,只有我在循环结束时加入的Thread.sleep(100) – user2650166

0

简单......与
Dispatcher.Invoke((Action)(() => { Hello(); }));

你再次调用这个循环回到WPF Dispat cher线程,让你!不要!使用multithreding

我的建议......都告知自己更多的线程,回调和任务在C#中,比开始WPF使用它

0

你并不需要“一个窗口上应用两个线程” ...

你有你的UI线程,你需要一个第二个线程从COM端口获取数据并将其发送到您的UI线程。

您可以使用例如BackgroundWorker类。并通过附加事件将数据发送到UI线程,在那里捕获触发的事件并将发送的数据附加到文本框中。

0

如果你打算进行任何长时间运行的任务,可以在后台,我建议你看一看的BackgroundWorker类来完成。

否则,您可能需要查看TaskTaskFactory类,以获取不太复杂的工作(和代码)。

0

这是最简单的方法:

private void startWrite(object sender, RoutedEventArgs e) 
{ 
    startButton.IsEnabled = false; 
    stopButton.IsEnabled = true; 
    _continue = true; 
    Thread myThread = new Thread(startWriteThread); 
    startWriteThread.Start(); 
} 

private void startWriteThread() 
{ 
    Hello(); 
} 

我这样做,不过,建议您遵循建议的@Jurgen金瑞利的建议,因为它是一个更简洁的方法。