Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/338.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C#使用数据流块缓冲区的异步等待<;T>;_C#_.net_Asynchronous_Async Await_Tpl Dataflow - Fatal编程技术网

C#使用数据流块缓冲区的异步等待<;T>;

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

我有一个Winform应用程序,它需要同时管理几个状态机。每个状态机可能有一个套接字、串行端口或其他外部连接

下面是我的状态机shell,它使用async/await和dataflow BlockBuffer作为消息队列来实现

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());
        }
    }
}