ワーカーのデモプログラム
ソースコード
ファイル名:WpfChannelWorker.csproj
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<OutputType>WinExe</OutputType>
<TargetFramework>net10.0-windows</TargetFramework>
<Nullable>enable</Nullable>
<ImplicitUsings>enable</ImplicitUsings>
<UseWPF>true</UseWPF>
</PropertyGroup>
</Project>
ファイル名:CounterWorker.cs
using System.Threading.Channels;
namespace WpfChannelWorker;
// ==========================================
// カウントアップ専用ワーカー
// ==========================================
public sealed class CounterWorker
{
// -------- メッセージ --------
private record Request(TaskCompletionSource<int> Completion);
// -------- リクエストキュー --------
private readonly Channel<Request> _channel =
Channel.CreateUnbounded<Request>();
// -------- ワーカー内部状態 --------
private int _counter = 0;
public CounterWorker()
{
// 常駐ワーカー起動
_ = Task.Run(WorkerLoop);
}
// ==========================================
// UI から呼ぶ唯一の API
// ==========================================
public async Task<int> CountUpAsync()
{
var tcs = new TaskCompletionSource<int>();
await _channel.Writer.WriteAsync(
new Request(tcs));
return await tcs.Task;
}
// ==========================================
// ワーカー本体(単一スレッド Actor)
// ==========================================
private async Task WorkerLoop()
{
await foreach (var req in _channel.Reader.ReadAllAsync())
{
// 疑似的な重い処理
await Task.Delay(300);
_counter++;
req.Completion.SetResult(_counter);
}
}
}
ファイル名:MainWindow.xaml.cs
using System.Windows;
namespace WpfChannelWorker;
public partial class MainWindow : Window
{
private readonly CounterWorker _worker = new();
public MainWindow()
{
InitializeComponent();
Btn.Click += Btn_Click;
}
private async void Btn_Click(object sender, RoutedEventArgs e)
{
int value = await _worker.CountUpAsync();
Btn.Content = value.ToString();
}
}
ファイル名:MainWindow.xaml
<Window x:Class="WpfChannelWorker.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:local="clr-namespace:WpfChannelWorker"
mc:Ignorable="d"
Title="Channel Worker"
FontSize="20"
Height="200" Width="300">
<Grid>
<Button x:Name="Btn"
Content="0"
Width="140"
Height="40"/>
</Grid>
</Window>
実行例
ボタンを押すと表示されている数値がカウントアップされます。




コメント