gpt4 book ai didi

c# - .NET 中是否可以使用非阻塞、单线程、异步 Web 服务器(如 Node.js)?

转载 作者:IT老高 更新时间:2023-10-28 21:51:38 29 4
gpt4 key购买 nike

我在看 this question ,寻找一种在 .NET 中创建单线程、基于事件的非阻塞异步 Web 服务器的方法。

This answer起初看起来很有希望,声称代码的主体在单个线程中运行。

但是,我在 C# 中对此进行了测试:

using System;
using System.IO;
using System.Threading;

class Program
{
static void Main()
{
Console.WriteLine(Thread.CurrentThread.ManagedThreadId);

var sc = new SynchronizationContext();
SynchronizationContext.SetSynchronizationContext(sc);
{
var path = Environment.ExpandEnvironmentVariables(
@"%SystemRoot%\Notepad.exe");
var fs = new FileStream(path, FileMode.Open,
FileAccess.Read, FileShare.ReadWrite, 1024 * 4, true);
var bytes = new byte[1024];
fs.BeginRead(bytes, 0, bytes.Length, ar =>
{
sc.Post(dummy =>
{
var res = fs.EndRead(ar);

// Are we in the same thread?
Console.WriteLine(Thread.CurrentThread.ManagedThreadId);
}, null);
}, null);
}
Thread.Sleep(100);
}
}

结果是:

1
5

所以看起来,与答案相反,启动读取的线程和结束读取的线程相同。

所以现在我的问题是,如何在 .NET 中实现单线程、基于事件的非阻塞异步 Web 服务器?

最佳答案

整个SetSynchronizationContext 是一条红鲱鱼,这只是一种编码机制,工作仍然发生在IO 线程池中。

您要求的是一种排队和收获的方法Asynchronous Procedure Calls从主线程进行所有 IO 工作。许多更高级别的框架都封装了这种功能,最著名的是 libevent .

这里有各种选项的精彩回顾:Whats the difference between epoll, poll, threadpool? .

.NET 已经通过一个特殊的“IO 线程池”为您处理扩展,当您调用 BeginXYZ 方法时该池处理 IO 访问。此 IO 线程池必须在盒子上的每个处理器上至少有 1 个线程。见:ThreadPool.SetMaxThreads .

如果单线程应用程序是一项关键要求(出于某种疯狂的原因),您当然可以在使用 DllImport 时互操作所有这些东西。 (见 example here)

但它会是一个非常complex and risky task :

Why don't we support APCs as a completion mechanism? APCs are really not a good general-purpose completion mechanism for user code. Managing the reentrancy introduced by APCs is nearly impossible; any time you block on a lock, for example, some arbitrary I/O completion might take over your thread. It might try to acquire locks of its own, which may introduce lock ordering problems and thus deadlock. Preventing this requires meticulous design, and the ability to make sure that someone else's code will never run during your alertable wait, and vice-versa. This greatly limits the usefulness of APCs.

所以,回顾一下。如果您想要一个使用 APC 和完成端口完成所有工作的单线程托管进程,您将不得不手动对其进行编码。 build 它既冒险又棘手。

如果您只是想要高规模网络,您可以继续使用 BeginXYZ 和家人并放心,它会运行良好,因为它使用 APC。在线程和 .NET 特定实现之间编码东西需要付出很小的代价。

发件人:http://msdn.microsoft.com/en-us/magazine/cc300760.aspx

The next step in scaling up the server is to use asynchronous I/O. Asynchronous I/O alleviates the need to create and manage threads. This leads to much simpler code and also is a more efficient I/O model. Asynchronous I/O utilizes callbacks to handle incoming data and connections, which means there are no lists to set up and scan and there is no need to create new worker threads to deal with the pending I/O.

一个有趣的附带事实是,单线程并不是在 Windows 上使用完成端口执行异步套接字的最快方法,请参阅:http://doc.sch130.nsc.ru/www.sysinternals.com/ntw2k/info/comport.shtml

The goal of a server is to incur as few context switches as possible by having its threads avoid unnecessary blocking, while at the same time maximizing parallelism by using multiple threads. The ideal is for there to be a thread actively servicing a client request on every processor and for those threads not to block if there are additional requests waiting when they complete a request. For this to work correctly however, there must be a way for the application to activate another thread when one processing a client request blocks on I/O (like when it reads from a file as part of the processing).

关于c# - .NET 中是否可以使用非阻塞、单线程、异步 Web 服务器(如 Node.js)?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/8905860/

29 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com