我正在开发一个需要以下逻辑的Web服务:
原因是消息的经纪人在知道之前并不想等我们完成我们的(可能是长期运行的&#34 ;;< 10s可能< 1s)逻辑我们已经收到了请求。
我看到的一个选项是简单地写入日志并返回,让定时作业处理来自日志的消息,但这似乎过多(尽管我们计划将其作为备份实现)。
我的工作解决方案是在传递消息的消息处理程序中生成Task
,但我对线程知识不足以了解离开孤立{{1}时可能出现的问题周围。以下是此解决方案:
Task
这对我来说是不是很糟糕? public class LoggingHandler : DelegatingHandler
{
protected async override Task<HttpResponseMessage> SendAsync(
HttpRequestMessage request,
CancellationToken cancellationToken)
{
string content = await request.Content.ReadAsStringAsync();
HttpRequestHeaders header = request.Headers;
HttpMethod method = request.Method;
Uri uri = request.RequestUri;
Version version = request.Version;
IDictionary<string, object> properties = request.Properties;
// Reset content. This might not be necessary, but due to the fact
// HttpRequestMessage.Content is only meant to be read once it's
// here to be safe.
request.Content = new StringContent(content);
bool messageLogged = true;
// Write content to message table
if (!messageLogged)
{
return new HttpResponseMessage(
System.Net.HttpStatusCode.InternalServerError);
}
#pragma warning disable CS4014 // Because this call is not awaited, execution of the current method continues before the call is completed
Task.Run(() =>
{
try
{
base.SendAsync(request, cancellationToken).Wait();
}
catch (Exception)
{
}
});
#pragma warning restore CS4014 // Because this call is not awaited, execution of the current method continues before the call is completed
return new HttpResponseMessage(System.Net.HttpStatusCode.OK);
}
}
可以抛出异常(内存不足等等),会导致什么结果?我是否会遇到线程池的问题?
简而言之,这个问题是否有正确的解决方案?
答案 0 :(得分:2)
我认为这是建筑问题。
我会考虑将消息队列用于长时间运行的任务。它可以是最简单形式的内存实现。您始终可以创建一些逻辑来重试消息并更新日志/表中消息项的状态。
但是如果你想要一个更强大的消息处理,我宁愿使用一个消息代理,如RabbitMQ,Azure Service Bus +等等。它们为您提供消息恢复,并使您能够使用各种模式来实现消息的处理方式。
所以我的建议是长期运行的任务: