1

我是 .net 的新手,我正在尝试在一个窗口上应用两个线程

该应用程序包含两个按钮(开始和停止)和一个只读文本框,当用户单击启动时,程序将从 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;
        }
    }
}
}

xml代码:

<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>

对不起我的英语

4

5 回答 5

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");
            }));                
        }
    }
}
于 2013-08-04T10:51:50.080 回答
0

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

您在 WPF 调度程序线程中再次调用此循环,所以您!不要!使用多线程

我的建议... 更多地了解 C# 中的线程、回调和任务,而不是开始在 WPF 中使用它

于 2013-08-04T10:40:14.837 回答
0

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

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

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

于 2013-08-04T10:46:23.343 回答
0

如果您要执行可以在后台完成的任何长时间运行的任务,我建议您查看BackgroundWorker类。

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

于 2013-08-04T10:46:32.050 回答
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 Camilleri 的建议,因为这是一种更清洁的方法。

于 2013-08-04T10:49:09.233 回答