C#使用数据流块缓冲区的异步等待<;T>;
我有一个Winform应用程序,它需要同时管理几个状态机。每个状态机可能有一个套接字、串行端口或其他外部连接 下面是我的状态机shell,它使用async/await和dataflow BlockBuffer作为消息队列来实现C#使用数据流块缓冲区的异步等待<;T>;,c#,.net,asynchronous,async-await,tpl-dataflow,C#,.net,Asynchronous,Async Await,Tpl Dataflow,我有一个Winform应用程序,它需要同时管理几个状态机。每个状态机可能有一个套接字、串行端口或其他外部连接 下面是我的状态机shell,它使用async/await和dataflow BlockBuffer作为消息队列来实现 using System.Threading; using System.Threading.Tasks; using System.Threading.Tasks.Dataflow; using System.Windows.Forms; public class S
using System.Threading;
using System.Threading.Tasks;
using System.Threading.Tasks.Dataflow;
using System.Windows.Forms;
public class StateMachineMessage
{
private static int id = 1;
public int Id { get; } = 0;
public string Name { get; }
public string Text { get; }
public BufferBlock<StateMachineMessage> Queue { get; set; }
public StateMachineMessage(string name, string text)
{
Id = Interlocked.Increment(ref id);
Name = name;
Text = text;
Queue = null;
}
public StateMachineMessage(string name, string text, BufferBlock<StateMachineMessage> queue)
{
Id = Interlocked.Increment(ref id);
Name = name;
Text = text;
Queue = queue;
}
public override string ToString()
{
return "(" + Id + ":" + Name + ":" + Text + ")";
}
}
public class StateMachine
{
private int State { get; }
public string Name { get; }
RichTextBox TextBox { get; }
BufferBlock<StateMachineMessage> Queue { get; }
public StateMachine(string name, BufferBlock<StateMachineMessage> queue, RichTextBox textBox)
{
Name = name;
Queue = queue;
TextBox = textBox;
}
public async Task StartAsync()
{
while (await Queue.OutputAvailableAsync())
{
var request = await Queue.ReceiveAsync();
TextBox.AppendText(string.Format("{0}: {1}: {2}\n",
Thread.CurrentThread.ManagedThreadId,
Name, request));
if (request.Queue != null)
{
var response = new StateMachineMessage("RESPONSE", "Good Morning!");
TextBox.AppendText(string.Format("{0}: {1}: {2}\n",
Thread.CurrentThread.ManagedThreadId,
Name, response));
await request.Queue.SendAsync(response);
}
}
}
}
使用系统线程;
使用System.Threading.Tasks;
使用System.Threading.Tasks.Dataflow;
使用System.Windows.Forms;
公共类状态机消息
{
私有静态int id=1;
公共int Id{get;}=0;
公共字符串名称{get;}
公共字符串文本{get;}
公共缓冲块队列{get;set;}
public StateMachineMessage(字符串名称、字符串文本)
{
Id=联锁增量(参考Id);
名称=名称;
文本=文本;
队列=空;
}
public StateMachineMessage(字符串名称、字符串文本、缓冲块队列)
{
Id=联锁增量(参考Id);
名称=名称;
文本=文本;
队列=队列;
}
公共重写字符串ToString()
{
返回“(“+Id+”:“+Name+”:“+Text+”)”;
}
}
公共类状态机
{
私有int状态{get;}
公共字符串名称{get;}
RichTextBox文本框{get;}
缓冲块队列{get;}
公共状态机(字符串名称、缓冲块队列、RichTextBox)
{
名称=名称;
队列=队列;
TextBox=TextBox;
}
公共异步任务StartAsync()
{
while(wait Queue.OutputAvailableAsync())
{
var request=wait Queue.ReceiveAsync();
TextBox.AppendText(string.Format(“{0}:{1}:{2}\n”,
Thread.CurrentThread.ManagedThreadId,
姓名、请求);
if(request.Queue!=null)
{
var response=newstatemachinemessage(“response”,“早上好!”);
TextBox.AppendText(string.Format(“{0}:{1}:{2}\n”,
Thread.CurrentThread.ManagedThreadId,
姓名,答复);;
等待请求.队列.发送异步(响应);
}
}
}
}
主窗体在初始化时创建数据流块缓冲区和状态机
using System;
using System.Threading;
using System.Threading.Tasks;
using System.Threading.Tasks.Dataflow;
using System.Windows.Forms;
namespace DataflowThread
{
public partial class Form1 : Form
{
// Enables the user interface to signal cancellation.
CancellationTokenSource cancellationSource;
// The worker state machine and dataflow node
StateMachine workerMachine;
BufferBlock<StateMachineMessage> workQueue;
// The main thread state machine
StateMachine mainMachine;
BufferBlock<StateMachineMessage> mainQueue;
// Enables progress bar actions to run on the UI thread.
TaskScheduler uiTaskScheduler;
public Form1()
{
InitializeComponent();
InitializeDataflow();
StartStateMachines();
}
public void InitializeDataflow()
{
// Create the cancellation source.
cancellationSource = new CancellationTokenSource();
// Create the UI task scheduler from the current sychronization context.
uiTaskScheduler = TaskScheduler.FromCurrentSynchronizationContext();
// Create dataflow options
var options = new ExecutionDataflowBlockOptions();
options.CancellationToken = cancellationSource.Token;
options.TaskScheduler = uiTaskScheduler;
// Create dataflow nodes for the main thread and worker state machines
mainQueue = new BufferBlock<StateMachineMessage>(options);
workQueue = new BufferBlock<StateMachineMessage>(options);
// Create the state machines for the worker and main thread
mainMachine = new StateMachine("MainMach", mainQueue, richTextBox1);
workerMachine = new StateMachine("WorkerMach", workQueue, richTextBox2);
}
public void StartStateMachines()
{
var mainTask = mainMachine.StartAsync();
var workerTask = workerMachine.StartAsync();
}
~Form1()
{
cancellationSource.Dispose();
}
private void sendButton_Click(object sender, EventArgs e)
{
var request = new StateMachineMessage("REQUEST", "Hello World!", mainQueue);
richTextBox1.AppendText(string.Format("{0}: {1}: {2}\n",
Thread.CurrentThread.ManagedThreadId,
mainMachine.Name, request));
workQueue.Post(request);
}
private async void cancelButton_Click(object sender, EventArgs e)
{
try
{
workQueue.Complete();
mainQueue.Complete();
await Task.WhenAll(workQueue.Completion, mainQueue.Completion);
richTextBox1.AppendText("All queues Completed\n");
resetButton.Enabled = true;
}
catch (OperationCanceledException ex)
{
richTextBox1.AppendText(ex.ToString());
}
}
private void sendTenButton_Click(object sender, EventArgs e)
{
for (int i = 0; i < 10; i ++)
{
var request = new StateMachineMessage("REQUEST", "Hello World!", mainQueue);
richTextBox1.AppendText(string.Format("{0}: {1}: {2}\n",
Thread.CurrentThread.ManagedThreadId,
mainMachine.Name, request));
workQueue.Post(request);
}
}
private void resetButton_Click(object sender, EventArgs e)
{
resetButton.Enabled = false;
InitializeDataflow();
StartStateMachines();
richTextBox1.Clear();
richTextBox2.Clear();
}
}
}
使用系统;
使用系统线程;
使用System.Threading.Tasks;
使用System.Threading.Tasks.Dataflow;
使用System.Windows.Forms;
命名空间数据流线程
{
公共部分类Form1:Form
{
//允许用户界面发出取消信号。
CancellationTokenSource cancellationSource;
//工作状态机和数据流节点
状态机;
缓冲块工作队列;
//主线程状态机
状态机;
缓冲块主队列;
//允许进度条操作在UI线程上运行。
任务调度器uiTaskScheduler;
公共表格1()
{
初始化组件();
初始化数据流();
StartStateMachines();
}
public void InitializeDataflow()
{
//创建取消源。
cancellationSource=新的CancellationTokenSource();
//从当前同步上下文创建UI任务计划程序。
uiTaskScheduler=TaskScheduler.FromCurrentSynchronizationContext();
//创建数据流选项
var options=新的ExecutionDataflowBlockOptions();
options.CancellationToken=cancellationSource.Token;
options.TaskScheduler=uiTaskScheduler;
//为主线程和工作状态机创建数据流节点
mainQueue=新的缓冲块(选项);
工作队列=新缓冲块(选项);
//为辅助线程和主线程创建状态机
mainMachine=新状态机(“MainMach”,mainQueue,richTextBox1);
workerMachine=新状态机(“WorkerMach”,workQueue,richTextBox2);
}
公共无效StartStateMachines()
{
var mainTask=mainMachine.StartAsync();
var workerTask=workerMachine.StartAsync();
}
~Form1()
{
cancellationSource.Dispose();
}
私有无效发送按钮\单击(对象发送程序,事件参数e)
{
var request=newstateMachineMessage(“request”,“helloworld!”,mainQueue);
richTextBox1.AppendText(string.Format(“{0}:{1}:{2}\n”,
Thread.CurrentThread.ManagedThreadId,
main machine.Name,request);
工作队列.Post(请求);
}
私有异步作废取消按钮\u单击(对象发送方,事件参数e)
{
尝试
{
workQueue.Complete();
mainQueue.Complete();
等待任务.WhenAll(workQueue.Completion,mainQueue.Completion);
richTextBox1.AppendText(“所有队列已完成\n”);
resetButton.Enabled=true;
}
捕捉(操作取消例外)
{
richTextBox1.AppendText(例如ToString());
}
}
私有void sendTenButton_单击(对象发送者,事件参数e)
{
对于(int i=0;i<10;i++)
{
var request=newstateMachineMessage(“request”,“helloworld!”,mainQueue);
richTextBox1.AppendText(string.Format(“{0}:{1}:{2}\n”,
Thread.CurrentThread.ManagedThreadId,
main machine.Name,request);
工作队列.Post(请求);
}
}
私有无效重置按钮\单击(对象发送者,事件参数e)
{
resetButton.Enabled=false;
初始化数据流();
StartStateMachines();
里克
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using System.Windows.Forms;
namespace DataflowThread
{
static class Program
{
/// <summary>
/// The main entry point for the application.
/// </summary>
[STAThread]
static void Main()
{
Application.EnableVisualStyles();
Application.SetCompatibleTextRenderingDefault(false);
Application.Run(new Form1());
}
}
}