我正在与
HttpListener
斗争并等待它的上下文。有时候我真的很迷茫。我有运行此服务器的应用程序。但是,我不想等待请求。我想在后台运行服务器并且不关心它。但我不确定这是否是一个好主意,因为微软说如果你有类似 I/O 操作的东西,它应该被等待。但我不想等待它。如果我想在我的控制台中写一些东西怎么办?我不能,因为我等待 HttpListener 的上下文。解决方案看起来很简单:
// _server is an instance of HttpListener
public void StartServer()
{
_server.Prefixes.Add("http://127.0.0.1:8080/test/");
_server.Start();
Task.Run(async() =>
{
while (_server.IsListening)
{
HttpListenerContext context = await _server.GetContextAsync();
await HandleContextAsync(context);
}
}).ConfigureAwait(false);
}
但是,在这种情况下,我不确定不会有任何死锁或其他东西,因为处理上下文需要很多操作(例如,它在某处打开一个数据库连接)。
我决定做的最后一件事是将我的主应用程序和服务器端分开,但我仍然想在后台运行服务器以便能够使用来自控制台的一些输入来停止它。我该怎么办?
我也尝试过这样的事情:
Task serverListener = server.StartServerAsync();
Console.ReadLine();
await server.StopServerAsync();
//
// The server methods:
//
public async Task StartServerAsync()
{
_server.Prefixes.Add("http://127.0.0.1:8080/test/");
_server.Start();
while (_server.IsListening)
{
HttpListenerContext context = await _server.GetContextAsync();
await HandleContextAsync(context);
}
}
public Task StopServerAsync()
{
_server.Stop();
_server.Close();
return Task.CompletedTask;
}
但在这种情况下,我不确定 Task 会发生什么,因为它没有被取消或其他什么。服务器已停止,但任务仍在等待。是不是比第一个有
Task.Run()
的情况好呢?
但是,在这种情况下,我不确定不会有任何死锁或其他东西
不,这不会引入任何死锁(除了你已经有的死锁)。
Task.Run
安排线程池上的代码执行,该线程池不会“流动”SynchronizationContext
,这是导致几种与异步相关的死锁的臭名昭著的原因。
我也尝试过这样的事情: 但在这种情况下,我不确定 Task 会发生什么,因为它没有被取消或其他什么。
操作系统将在应用程序关闭时清理所有请求的资源。由于侦听器被停止,
StartServerAsync
任务本身将设置为异常结果,但由于没有等待,因此不会观察到异常(尽管我认为在这种情况下没问题)就是这样。
阅读更多: