如何在 C# 中的同一线程上收听标准输入和套接字?
Posted
技术标签:
【中文标题】如何在 C# 中的同一线程上收听标准输入和套接字?【英文标题】:How to listen to standard in and a socket on the same thread in C#? 【发布时间】:2010-02-05 19:12:56 【问题描述】:我正在尝试制作一个基于网络控制台的应用程序,但它需要能够同时监听标准输入和来自套接字的输入。在 C++ 中,我会使用 posix select() 函数来执行此操作,但在 C# 中,the equivalent select function 似乎仅用于套接字。有没有一种方法可以在 C# 中同时监听两个输入,而无需借助多个线程?
【问题讨论】:
【参考方案1】:要等待多个输入,您需要为每个输入一个 WaitHandle,然后调用静态方法 WaitHandle.WaitAny。
但另一种选择是使用异步 IO。使用BeginXXXX
开始读取/接收操作。您在每种情况下都提供一个回调,该回调将在完成时执行。启动它们后,您等待监视器对象,并在回调中脉冲该监视器对象以通知完成。这是一种非常有效的多线程编程形式,但您不必显式启动任何线程。
要获取标准输入的原始流,请使用Console.OpenStandardInput。
【讨论】:
这似乎是一个很好的解决方案,我知道如何使用网络流来做到这一点,但是我如何使用标准输入来做同样的事情呢?【参考方案2】:我首先要说的是-不,您不能将Select()
用于标准输入。
但是,C#
为您提供了一种更好的方式来收听少数 I\O。
async\await
是一种更好的方法,因为它可以完全避免阻塞,即使对于调用函数也是如此。
在以下示例中,程序侦听 StandardInput with ReadAsync()
,同时 PrintStaff() 函数每 3 秒将变量 i
打印到控制台。
示例:
using System;
using System.Threading;
using System.IO;
using System.Text;
namespace AsyncExplore
class Program
static void Main(string[] args)
ReadFromConsole();
PrintStaff();
private static void PrintStaff()
int i = 0;
while (true)
Thread.Sleep(3000);
Console.WriteLine(i++);
private static async void ReadFromConsole()
while(true)
byte[] buffer = new byte[4000];
using Stream stdin = Console.OpenStandardInput();
//read from StandardInput without blocking, so the
//control yields to Main,
//and another function can run.
int numBytes = await stdin.ReadAsync(buffer, 0,
buffer.Length);
//convert the bytes[] to string
Console.WriteLine(Encoding.ASCII.GetString(buffer));
优点是
可读性:您可以轻松阅读序列。 编码:编码过程更直观,更接近同步方式。 零线程:您可以将此 Main 作为“侦听器”运行,而无需新线程。与 Select() 不同,Select() 需要您在 Select() 上保持阻塞状态,在这里您可以将整个函数设置为异步,从而将控制权返回给调用方方法。注意:在示例中,Main() 不是async
,为简化起见,因此它在while
循环中被“阻塞”。但是您也可以使PrintStaff()
异步,因此主要,await
在 PrintStaff() 上。在这种情况下,您可以完全解除对线程的阻塞。
【讨论】:
以上是关于如何在 C# 中的同一线程上收听标准输入和套接字?的主要内容,如果未能解决你的问题,请参考以下文章