Я новичок в потоковом режиме, и я действительно не знаю, как закодировать конкретную задачу. Я хотел бы обработать событие щелчка мыши в окне, которое начнет цикл while в отдельном потоке. Этот поток, отличный от потока пользовательского интерфейса, должен вызывать функцию в цикле while, которая обновляет метку в окне, обслуживаемом потоком пользовательского интерфейса. Цикл while должен прекратиться, если левая кнопка мыши больше не нажата. Весь цикл выполняет инкремент счетчика, а затем повторно вызывает функцию, которая отображает обновленное значение в окне. Код для окна и все потоки приведены ниже (я продолжаю получать некоторую ошибку о потоке STA, но не знаю, куда поместить атрибут). Кроме того, я надеюсь использовать это решение, если оно когда-либо работает, в другом проекте, который делает асинхронные вызовы в другом месте для службы через wcf, поэтому я надеялся не создавать какие-либо специальные конфигурации приложения, так как я действительно новый многопоточности и я очень беспокоюсь о нарушении другого кода в большей программе ... Вот что у меня есть:Многопоточный вопрос о WPF
<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();
}
}
}
в любом случае, многопоточность для меня это действительно ново, и у меня нет опыта его реализации, поэтому любые мысли или предложения приветствуются!
Спасибо,
Эндрю
Edit:
Вот другая версия (я также добавил сетку), используя 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();
}
}
}
@Mitch: Спасибо Mitch! Я изучаю ваши предложения - они кажутся действительно многообещающими. Я попытаюсь изменить код для использования BackgroundWorker, который, похоже, может работать. Я отправлю сообщение, как только попробую! – Andrew
@Mitch: Хорошо, я пробовал использовать BackgroundWorker, но, похоже, у меня проблема с STAThread. Не совсем уверен, какое лучшее решение для этого. Я отправлю версию BackgroundWorker в «Редактирование» в исходный вопрос ... – Andrew
@Andrew: вы подключаете обработчик событий ProgressChanged и используете только это и обработчик Completed для обновления пользовательского интерфейса? –