为了账号安全,请及时绑定邮箱和手机立即绑定

哪个层应该在 .NET 中的 N 层架构模式中填充并发和任务

哪个层应该在 .NET 中的 N 层架构模式中填充并发和任务

C#
哈士奇WWW 2022-10-23 16:42:47
如果这个问题离题,您可以在评论中写下稍后将其删除:)如果我有 3 层(*.DLL 的)数据访问层.DLL业务逻辑层.DLLUI 应用程序(WPF、WinForms、任何技术)在我的应用程序中,我让 BusinessLogicLayer 方法返回Task,在 UI 应用程序中,当我使用来自 BusinessLogicLayer 的方法时,我调用 await我有以下误解:Task 或并发应该支持哪一层(Back-End、Middle-were、Front)如果我需要为其他开发人员制作可重用的 BusinessLogicLayer,他们也可能忘记在处理他们的下一个项目中使用 UI 应用程序层中的等待/异步方法。如何在中间层实现等待方法,无需在每个 UI 事件(例如 Button_Click)中编写等待。如何使 DataAccessLayer 只包含并发和在 UI 层中等待,而不需要使用await、async关键字。我的简单代码包含以下内容:DataAccessLayer.DLL单一方法public void MoveNext(){    if (RecordCount == 0) return;    Tables[0].Query.Criteria.Clear();    Tables[0].Query.Sorting = $"ORDER BY {string.Join(" ASC, ",     Tables[0].Keys.Select(x => x.KeyID))} ASC";    FetchDataBuffer();}BusinessLogicLayer.DLL现在以简单的方式包装了数据访问的方法public Task MoveNext() => Task.Run(() => { EntryBase.MoveNext(); });UI 层(.NET 中的任何应用程序或前端提供程序) private async void BtnNext_ItemClick(object sender, ClickEventArgs e) {    await EntryLogic.MoveNext();    DeserializeBuffer(); }如上所示,在并发方法 ( MoveNext ) 完成之前, DeserializeBuffer方法不会执行。我需要做的是摆脱UI 层中的 await关键字和异步。我实际上做的是失败,不知道为什么会这样我尝试制作的场景如下:将 DataAccessLayer 的方法类型从void转换为Task   public Task MoveNext()   {      return Task.Run(() => {       if (RecordCount == 0) return;      Tables[0].Query.Criteria.Clear();      Tables[0].Query.Sorting = $"ORDER BY {string.Join(" ASC, ",       Tables[0].Keys.Select(x => x.KeyID))} ASC";      FetchDataBuffer();      });     }然后在中间层BusinessLogicLayer中调用await公共异步无效 MoveNext() => 等待 EntryBase.MoveNext();之后从逻辑层调用 UI 层中的 MoveNext。我想这会使它可以等待,因为它已经在中间层声明了等待。但实际上 UI 层同时执行下一个方法。所以抛出的异常是因为关闭下一个方法(DeserializeBuffer)取决于上一个方法(EntryLogic.MoveNext)  private async void BtnNext_ItemClick(object sender, ClickEventArgs e)  {    EntryLogic.MoveNext();    DeserializeBuffer();  // exception thrown        /* because EntryLogic.MoveNext      is still executing and not awaited */  }任何帮助,将不胜感激。
查看完整描述

1 回答

?
qq_花开花谢_0

TA贡献1835条经验 获得超7个赞

我需要做的是摆脱 UI 层中的 await 关键字和异步。

这是完全错误的。UI 层是唯一必须async使用的地方。而且它们确实必须在该层中使用。await

您的数据访问技术未指定,但从代码来看,我猜它可能是DataTable基于 - 的,这是有问题的,因为DataTable它非常旧并且不支持async. 请注意,使用“使它们异步”包装方法主体Task.Run是一种反模式- 这些实际上是伪异步方法,而不是真正的异步。

如果我错了并且您的数据访问技术确实支持async,那么您应该能够在async不使用Task.Run. 从最低级别开始(例如,FetchDataBuffer调用任何方法)并将它们更改为异步等效项。然后让async从那里成长。请注意,“让异步增长”意味着使用async Task,而不是async voidasync void在 BLL 中绝对是一种反模式

但是,如果我是对的并且您的 DAL 正在使用DataTable,那么您需要决定是否切换到更新的数据访问技术。如果这不是您现在可以做的事情,那么我建议保留现有的 DAL 和 BLL 代码,并将async/添加await到 UI 层:

private async void BtnNext_ItemClick(object sender, ClickEventArgs e)

{

  await Task.Run(() => EntryLogic.MoveNext());

  DeserializeBuffer();

}

这不是反模式,因为我们使用Task.Run的是调用方法——将其移出 UI 线程。这并不理想,因为我们仍在使用比必要更多的线程,但理想的解决方案需要真正的异步数据访问。通过这种妥协,您的 DAL 和 BLL 仍然处于阻塞状态,因此它们在桌面 UI 应用程序之外的使用受到限制。


查看完整回答
反对 回复 2022-10-23
  • 1 回答
  • 0 关注
  • 90 浏览

添加回答

举报

0/150
提交
取消
微信客服

购课补贴
联系客服咨询优惠详情

帮助反馈 APP下载

慕课网APP
您的移动学习伙伴

公众号

扫描二维码
关注慕课网微信公众号