【发布时间】:2018-06-08 08:22:40
【问题描述】:
我正在尝试实现一个简单的日志库,它将用于多个项目。库的工作是将 HTTP 请求发送到 ElasticSearch。这个库的要点是它不能等待响应。另外,我不关心任何错误/异常。它必须将请求发送到 ElasticSearch,并立即返回。我不想制作返回类型为Task 的接口,我希望它们保持void。
以下是我的示例代码。它是“一劳永逸”的正确和安全实施吗?如果我在高负载库中使用Task.Run() 可以吗?或者我应该避免在我的情况下使用Task.Run()?另外,如果我不使用await 和Task.Run(),我会阻塞线程吗?
此代码在库中:
public enum LogLevel
{
Trace = 1,
Debug = 2,
Info = 3,
Warn = 4,
Error = 5,
Fatal = 6
}
public interface ILogger
{
void Info(string action, string message);
}
public class Logger : ILogger
{
private static readonly HttpClient _httpClient = new HttpClient(new HttpClientHandler { Proxy = null, UseProxy = false });
private static IConfigurationRoot _configuration;
public Logger(IConfigurationRoot configuration)
{
_configuration = configuration;
}
public void Info(string action, string message)
{
Task.Run(() => Post(action, message, LogLevel.Info));
/*Post(action, message, LogLevel.Info);*/ // Or should I just use it like this?
}
private async Task Post(string action, string message, LogLevel logLevel)
{
// Here I have some logic
var jsonData = JsonConvert.SerializeObject(log);
var content = new StringContent(jsonData, Encoding.UTF8, "application/json");
var response = await _httpClient.PostAsync(_configuration.GetValue<string>("ElasticLogger:Url"), content);
// No work here, the end of the method
}
}
这就是我在我的 web api 的 Startup 类的 ConfigureServices 方法中注册记录器的方式:
public void ConfigureServices(IServiceCollection services)
{
// ......
services.AddSingleton<ILogger, Logger>();
// .....
}
此代码在我的 web api 中的一个方法中:
public void ExecuteOperation(ExecOperationRequest request)
{
// Here some business logic
_logger.Info("ExecuteOperation", "START"); // Log
// Here also some business logic
_logger.Info("ExecuteOperation", "END"); // Log
}
【问题讨论】:
-
如果可能的话,我会考虑看看 Serilog 和 Elastic Sink,它可能会为你省去很多麻烦:github.com/serilog/serilog-sinks-elasticsearch
-
“我不关心任何错误/异常”——那么最简单的实现肯定是假设每个请求都会出错,因此什么都不做?
-
标签: c# asynchronous asp.net-core async-await task