使用异步回调方式解决等待耗时问题
在开发过程中,会遇到这样的场景:从客户端发起调用,这个调用的API耗时比较长,
通常解决方式是在服务端起一个线程去单独执行这块耗时的逻辑,主线程则直接返回结果。但是这样会遇到两个问题:
1.主线程中的数据传递问题
2.子线程处理完结果后,客户端怎么知道结果问题(如果客户端不需要结果则忽略)
解决第一个问题比较简单,主要是提醒一下别忘了传值。
而解决第二个问题则需要使用通知的方式,可以是RPC的通知,也可也使用SignalR做消息推送,也可以使用MQ通知,为了演示效果,我这边写了个demo使用的是RPC的方式
这种方式最简单
Client:
public class Client { private static ILogger<Client> _logger; public void DeleteFile() { _logger = MyLogger.GetLogger<Client>(); Service service = new Service(); service.DeleteFile(CallBack); } public bool CallBack() { _logger.LogInformation("RPC call the Client logics"); return true; } }
Service:
public class Service { private static ILogger<Service> _logger; public void DeleteFile(Func<bool> callBack) { _logger = MyLogger.GetLogger<Service>(); System.Threading.Tasks.Task.Run(() => { for (int i = 0; i < 100; i++) { _logger.LogInformation($"this is {i}"); } callBack.Invoke(); _logger.LogInformation("invoke callback done"); }); } }
为了演示效果集成了Nlog
Nlog.config
<?xml version="1.0" encoding="utf-8" ?> <!-- XSD manual extracted from package NLog.Schema: https://www.nuget.org/packages/NLog.Schema--> <nlog xmlns="http://www.nlog-project.org/schemas/NLog.xsd" xsi:schemaLocation="NLog NLog.xsd" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" autoReload="true" internalLogFile="c:\temp\console-example-internal.log" internalLogLevel="Info" > <!-- the targets to write to --> <targets> <!-- write logs to file --> <target xsi:type="File" name="logfile" fileName="c:\temp\console-example.log" layout="${longdate}|${level}|${message} |${all-event-properties} ${exception:format=tostring}" /> <target xsi:type="Console" name="logconsole" layout="${longdate}|${level}|${message} |${all-event-properties} ${exception:format=tostring}" /> </targets> <!-- rules to map from logger name to target --> <rules> <logger name="*" minlevel="Trace" writeTo="logfile,logconsole" /> </rules> </nlog>
MyLogger:
public class MyLogger { public static ILogger<T> GetLogger<T>() { var logger = LoggerFactory.Create(builder => builder.AddNLog()).CreateLogger<T>(); return logger; } }
这个代码非常简单,主要是验证一下自己的想法,解决项目上的一个问题