mainBw
UI (WPF) スレッドでBackgroundWorker () を作成しました。1.5秒間スリープしApplication.Current.Dispatcher.Invoke
、「グローバル」text
変数からTextBoxにテキストを出力するだけの関数を呼び出す無限ループがあります。
また、ループの前に、別の ( child
) ReportsProgress を作成する BackgroundWorker を作成し、ProgressChanged イベント ハンドラーでtext
変数を変更します。
mainBw
ループ内にWinFormsの Application.DoEvents() みたいなものがなくてイベントハンドラを処理できないのでうまくいかないと思っていました。しかし、それは機能します。なんで?
コードは次のとおりです。
using System;
using System.ComponentModel;
using System.Threading;
using System.Windows;
namespace WpfApplication6
{
public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
}
private BackgroundWorker mainBw = new BackgroundWorker();
private void Button_Click(object sender, RoutedEventArgs e)
{
mainBw.DoWork += MainBwOnDoWork;
mainBw.RunWorkerAsync();
btn.IsEnabled = false;
}
private string text = "abc";
private void MainBwOnDoWork(object sender, DoWorkEventArgs e)
{
BackgroundWorker bw = new BackgroundWorker();
bw.DoWork += BwOnDoWork;
bw.ProgressChanged += BwOnProgressChanged;
bw.WorkerReportsProgress = true;
bw.RunWorkerAsync();
while (true)
{
Thread.Sleep(1500);
text += " main ";
Application.Current.Dispatcher.Invoke(new Action(() => { WriteToUIThread(); }));
}
}
private void WriteToUIThread()
{
tbox.Text = DateTime.Now + " " + text + Environment.NewLine + tbox.Text;
}
private void BwOnProgressChanged(object sender, ProgressChangedEventArgs e)
{
text += e.UserState.ToString();
}
private void BwOnDoWork(object sender, DoWorkEventArgs doWorkEventArgs)
{
while (true)
{
Thread.Sleep(3000);
(sender as BackgroundWorker).ReportProgress(0, "child");
}
}
}
}
// XAML
<Window x:Class="WpfApplication6.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="MainWindow" Height="350" Width="525">
<Grid>
<Button Name="btn" Content="Button" HorizontalAlignment="Left" Height="105" Margin="43,47,0,0" VerticalAlignment="Top" Width="165" Click="Button_Click"/>
<TextBox Name="tbox" HorizontalAlignment="Left" Height="114" TextWrapping="Wrap" Text="TextBox" VerticalAlignment="Top" Width="456" Margin="27,182,0,0"/>
</Grid>
</Window>