当前位置: 首页 > news >正文

公司网站建设报价教人做家务的网站

公司网站建设报价,教人做家务的网站,企业网络维护一般多少钱,佛山市网站建站网站1、背景最近#xff0c;一个工作了一个月的同事离职了#xff0c;所做的东西怼了过来。一看代码#xff0c;惨不忍睹#xff0c;一个方法六七百行#xff0c;啥也不说了吧#xff0c;实在没法儿说。介绍下业务场景吧#xff0c;一个公共操作A#xff0c;业务中各个地方… 1、背景  最近一个工作了一个月的同事离职了所做的东西怼了过来。一看代码惨不忍睹一个方法六七百行啥也不说了吧实在没法儿说。介绍下业务场景吧一个公共操作A业务中各个地方都会做A操作正常人正常思维应该是把A操作提取出来封装其他地方调用可这哥们儿偏偏不这么干代码到处复制。仔细分析了整个业务之后发现是一个典型的事件/消息驱动型或者叫发布/订阅型的业务逻辑。鉴于系统是单体的所以想到利用进程内发布/订阅的解决方案。记得很久之前做WPF时候用过Prism的EventAggregator是不是暴露年龄了。。。那玩意儿不知道现在还在不在支不支持core目前流行的是MediatR跟core的集成也好于是决定采用MediatR。2.Demo代码Startup服务注册 服务1public class Service1 : IService1 {private readonly ILogger _logger;private readonly IMediator _mediator;private readonly IContext _context;private readonly IService2 _service2;public Service1(ILoggerService1 logger, IMediator mediator, IContext context) { _logger logger; _mediator mediator; _context context;//_service2 service2; }public async Task Method() { _context.CurrentUser test;//await _service2.Method();//_service2.Method();await _mediator.Publish(new SomeEvent());//_mediator.Publish(new SomeEvent());await Task.CompletedTask; } }  可以看到在服务1的method方法中发布了SomeEvent事件消息。服务2代码public class Service2 : IService2 {private readonly ILogger _logger;private readonly IContext _context;public Service2(ILoggerService2 logger, IContext context) { _logger logger; _context context; }public async Task Method() { _logger.LogDebug(当前用户:{0}, _context.CurrentUser);await Task.Delay(5000);//_logger.LogDebug(当前用户:{0}, _context.CurrentUser); _logger.LogDebug(Service2 Method at :{0}, DateTime.Now); } }解释下为啥服务2 Method方法中要等待5秒因为实际项目中有这么一个操作把一个压缩程序包传递到远端然后在远端代码操作IIS创建站点这玩意儿非常耗时大概要1分多钟这里我用5s模拟意思意思。这个5s至关重要待会儿会详述。再看事件订阅Handlerpublic class SomeEventHandler : INotificationHandlerSomeEvent, IDisposable {private readonly ILogger _logger;private readonly IServiceProvider _serviceProvider;private readonly IService2 _service2;public SomeEventHandler(ILoggerSomeEventHandler logger, IServiceProvider serviceProvider, IService2 service2) { _logger logger; _serviceProvider serviceProvider; _service2 service2; }public void Dispose() { _logger.LogDebug(Handler disposed at :{0}, DateTime.Now); }public async Task Handle(SomeEvent notification, CancellationToken cancellationToken) {await _service2.Method();//using (var scope _serviceProvider.CreateScope())//{// var service2 scope.ServiceProvider.GetServiceIService2();// await service2.Method();//} } }然后我们的入口Action[HttpGet(test)]public async TaskActionResultstring Test() { StringBuilder sb new StringBuilder(); sb.AppendFormat(开始时间{0}, DateTime.Now); sb.AppendLine();await _service1.Method(); sb.AppendFormat(结束时间{0}, DateTime.Now); sb.AppendLine();return sb.ToString(); }至此Demo要干的事情脉络应该很清晰了控制器接收HTTP请求然后调用Service1的Methodservice1的Method又发布消息消息处理器接收到消息调用Service2的Method完成后续操作。我们运行起来看下  http请求开始到结束耗时5s看似没问题。我们看系统输出日志 Service2的Method方法也确实被订阅执行了。3.问题  上述一切的一切看似没问题。运行成功没成功了。对不对好像也对。有没问题大大的问题HTTP从开始到结束要耗时5s实际项目中那是一分钟这整整一分钟你要前端挂起等待么一直理论上这种耗时的后端操作合理做法是HTTP迅速响应前端并返给前端业务ID前端根据此业务ID长轮询后端查询操作结果状态直至此操作完成决不能一直卡死的否则交互效果不说超过一定时间HTTP请求会直接超时的这就必须动刀子了将Service2操作后台任务化且不等待。Service1的Method代码调整如下public async Task Method() { _context.CurrentUser test;//await _service2.Method();//_service2.Method();//await _mediator.Publish(new SomeEvent()); _mediator.Publish(new SomeEvent());await Task.CompletedTask; }见注释前后改进地方只有一处发布事件代码去掉了await这样系统发布事件之后便不会等待Service2而是继续运行并立刻响应HTTP请求。好我们再来运行看下效果 我们看到系统立即响应了HTTP请求22:40:155s之后Service2才执行完成22:40:20。看似又没问题了。那是不是真的没问题呢我们注意Service1和Service2中都注入了一个Context上下文对象这个对象是我用来模拟一些Scope类型对象例如DBContext的代码如下public class Context : IContext, IDisposable {private bool _isDisposed false;private string _currentUser;public string CurrentUser {get {if (_isDisposed) {throw new Exception(Context disposed); }return _currentUser; }set {if (_isDisposed) {throw new Exception(Context disposed); } _currentUser value; } }public void Dispose() { _isDisposed true; } }里边就一个属性当前上下文用户并实现了Dispose模式并且当前上下文被释放时对该上下文对象任何操作将引发异常。从上文的Service1及Service2截图中我们看到了两个服务均注入了这个context对象Service1设置Service2中获取。现在我们将Service2的Method方法稍作调整如下public async Task Method() {//_logger.LogDebug(当前用户:{0}, _context.CurrentUser);await Task.Delay(5000); _logger.LogDebug(当前用户:{0}, _context.CurrentUser); _logger.LogDebug(Service2 Method at :{0}, DateTime.Now); }  调整只有一处就是获取当前上下文用户的操作从5s延时之前放到了5s延时之后。我们再来看看效果http请求上看貌似没问题立即响应了是吧。我们再看看程序日志输出WFTService2 Method没成功执行给了我一个异常。我们看看这个异常 Context dispose异常就是说上下文这时候已经被释放掉对它任何操作都无效并引发异常。很容易想到这里就是为了模拟DBContext这种通常为Scope类型的对象生命周期这种吊毛它就这样。为啥会释放因为HTTP请求结束那会儿core运行时就会Dispose相应scope类型对象注意释放不一定是销毁具体销毁时间不确定。那么怎么解决如果对基于DI生命周期比较熟悉就会知道这儿应该基于HTTP 的Scope之外单独起一个Scope了两个scope互补影响HTTP对应的scope结束另外的照常运行。我们将Handler处调整如下public async Task Handle(SomeEvent notification, CancellationToken cancellationToken) {//await _service2.Method();using (var scope _serviceProvider.CreateScope()) {var service2 scope.ServiceProvider.GetServiceIService2();await service2.Method(); } }  无非就是Handle中单独起了一个Scope。我们再看运行效果OKHTTP请求23:02:58响应Service2 Method 23:03:03执行完成。至此问题才算得到解决。顺便提一下大家注意看截图当前用户null因为scope之后原来的设置过CurrentUser的context已经释放掉了新开的scope中注入的context是另外的所以没任何信息。这里你可能会问了那我确实需要传递上下文怎么办答案是订阅事件本文中SomeEvent未定义任何信息如果你需要传递做对应调整即可比较简单也不是重点不做赘述。4、总结  感觉没什么好总结的。扎实细心实践没什么解决不了的。原文地址https://www.cnblogs.com/guokun/p/11001052.html.NET社区新闻深度好文欢迎访问公众号文章汇总 http://www.csharpkit.com
http://www.huolong8.cn/news/28984/

相关文章:

  • 长沙网站制作哪怎么做搜索网站
  • 企业网站怎么做推广做网站用语言
  • 上传文档网站开发平台公司实体化转型
  • 大型网站开发人员广州seo排名外包
  • 政务网站建设情况汇报河北一建停考
  • 秦皇岛工程建设信息网站水果网站开发所需的成本
  • 像饿了码的网站建站有吗网站建设中标签导航的特征
  • 北镇网站建设网站开发 发表文章
  • 专业网站建设技术网站建设的定位
  • 网站上面的头像怎么做的安康做网站公司
  • 网站和网页有什么区别汇鑫小学网站建设
  • 叫别人建个网站多少钱wordpress单页制作
  • 网站忘记备案做一个公众号多少钱
  • 查信息的网站有哪些郑州全域静态管理
  • 亚马逊中国官网网站济南建站价格
  • 做门户网站代码质量方面具体需要注意什么百度付费推广
  • 海南旅游网站开发背景重庆地推团队外包
  • 常州个人网站建设建站行业消失了吗
  • 湖南省建设工程造价总站网站中瑞网络网站建设流程
  • 婚介所网站开发费用网页设计图片怎么换
  • 提高网站速度大连三大网络推广网站
  • 个人建网站需要多少钱php第一季网站开发实例教程
  • 全球网站流量查询邳州建设银行招聘网站
  • 龙岗区住房和建设局官方网站手机百度网址大全
  • 网站建设找盛誉网络天元建设集团有限公司北京分公司
  • 浪潮云网站建设腾讯云服务器搭建网站
  • 长沙岳麓区网站建设设计店名logo
  • 沧州网站建设wordpress 前台文件上传
  • 含山县住房和城乡建设局网站联盟设计库
  • 电子商务网站推广的意义毕业设计旅游网网站设计