我是线程新手,我真的不知道如何编写特定任务。我想在窗口上处理鼠标单击事件,该事件将在单独的线程中启动while循环。该线程与UI线程不同,应调用while循环中的函数,该函数更新UI线程所服务的窗口上的标签。当不再按下鼠标左键时,while循环应该停止运行。所有循环都是递增计数器,然后重复调用在窗口中显示更新值的函数。下面给出了窗口和所有线程的代码(我不断收到有关STA线程的错误,但不知道将属性放在何处)。此外,我希望使用这个解决方案,如果它可以工作,在另一个项目,通过wcf在服务的其他地方进行异步调用,所以我希望不要进行任何应用程序范围的特殊配置,因为我真的是新的多线程,并且非常担心在更大的程序中破坏其他代码......这就是我所拥有的:
<Window x:Class="WpfApplication2.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="clr-namespace:WpfApplication2"
Name="MyMainWindow"
Title="MainWindow" Width="200" Height="150"
PreviewMouseLeftButtonDown="MyMainWindow_PreviewMouseLeftButtonDown">
<Label Height="28" Name="CounterLbl" />
</Window>
这是代码隐藏的代码:
using System.Windows;
using System.Windows.Input;
using System.Threading;
namespace WpfApplication2
{
/// <summary>
/// Interaction logic for MainWindow.xaml
/// </summary>
public partial class MainWindow : Window
{
private int counter = 0;
public MainWindow()
{
InitializeComponent();
}
private delegate void EmptyDelegate();
private void MyMainWindow_PreviewMouseLeftButtonDown(object sender, MouseButtonEventArgs e)
{
Thread counterThread = new Thread(new ThreadStart(MyThread));
counterThread.Start();
}
private void MyThread()
{
while (Mouse.LeftButton == MouseButtonState.Pressed)
{
counter++;
Dispatcher.Invoke(new EmptyDelegate(UpdateLabelContents), null);
}
}
private void UpdateLabelContents()
{
CounterLbl.Content = counter.ToString();
}
}
}
无论如何,多线程对我来说真的很新,而且我没有任何实现它的经验,所以欢迎任何想法或建议!
谢谢,
安德鲁
修改
这是使用BackgroundWorker的另一个版本(我还添加了一个网格),它仍然抱怨调用线程必须是STA ...
<Window x:Class="WpfApplication2.Window1"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="Window1"
Name="MyMainWindow" Width="200" Height="150" PreviewMouseLeftButtonDown="MyMainWindow_PreviewMouseLeftButtonDown">
<Grid>
<Label Height="28" Name="CounterLbl" />
</Grid>
</Window>
和背后的代码......
using System.Windows;
using System.Windows.Input;
using System.Threading;
using System.ComponentModel;
namespace WpfApplication2
{
/// <summary>
/// Interaction logic for MainWindow.xaml
/// </summary>
public partial class Window1 : Window
{
private int counter = 0;
public Window1()
{
InitializeComponent();
}
private delegate void EmptyDelegate();
private void MyMainWindow_PreviewMouseLeftButtonDown(object sender, MouseButtonEventArgs e)
{
BackgroundWorker bw = new BackgroundWorker();
bw.DoWork += new DoWorkEventHandler(MyThread);
bw.RunWorkerAsync(this);
}
private void MyThread(object sender, DoWorkEventArgs e)
{
Window window = e.Argument as Window;
while (Mouse.LeftButton == MouseButtonState.Pressed)
{
counter++;
window.Dispatcher.Invoke(new EmptyDelegate(UpdateLabelContents), null);
}
}
private void UpdateLabelContents()
{
CounterLbl.Content = counter.ToString();
}
}
}
答案 0 :(得分:2)
为简单起见,请使用BackgroundWorker
这个答案:Is this thread/background worker design for a C# WPF application OK?有其他建议,但在你的情况下,BackgroundWorker似乎很合适,特别是因为ProgressChanged要求。