【问题标题】:Running multiple tasks in one Service's method在一个服务的方法中运行多个任务
【发布时间】:2014-09-21 09:35:25
【问题描述】:

最好有一个简单的方法,它返回任务:

public class MessageService : IMessageService
{
    public Task<IEnumerable<Message>> DownloadMessagesTask()
    {
         return MyWebClient.GetMessages();
    }

现在,我想在本地存储中添加一个缓存:

    public Task<bool> WriteMessagesTask(IEnumerable<Message> list)
    {
        return MyIsoStorageManager.Write(list);
    }
    // same for reading

最天真的方法是从视图模型中调用它们:

    public async void Init()
    {
         var result = await messageService.ReadMessagesTask();
         if (result == null)
         {
             MessagesList = await messageService.DownloadMessagesTask();
             var writingResult = await messageService.WriteMessagesTask(MessagesList);
         }

但是我怎样才能将这个逻辑存储在服务中,以避免代码在另一个视图模型中重复?或者我应该保持服务清洁并在视图模型中调用任务?

【问题讨论】:

  • 在返回Task 的方法名称后面加上Async 是一个很好的约定
  • @RussCam 我认为返回Task的应该以*Task为后缀
  • 参见msdn.microsoft.com/en-us/library/hh873175.aspx,特别是命名、参数和返回类型
  • 将您的简单任务包装并组合到一个服务类中。任务创建确实有开销。
  • 从您的服务公开一个方法并从 VM 调用它。这个方法包装了你现在在你的 async Init() 中拥有的东西

标签: c# windows-phone-8 mvvm async-await mvvmcross


【解决方案1】:

从您的服务中公开一种方法,该方法包装了您现在拥有的 async void Init(),并从 VM 调用它。您还可以提取接口并将其注入您的视图模型(通过构造函数或属性)。

public class MyViewModel
{
    public MyViewModel()
        :this(new Service())
    {}

    public MyViewModel(IService service)
    {
        Service = service;
        Initialize();
    }

    public IService Service { get; set; }

    private async void Initialize()
    {
        // Fire forget
        await Service.DoSomething();
    }
}

public interface IService
{
    // change if you need to return something
    Task DoSomething();
}

public Service : IService
{
    public async Task DoSomething()
    {
        var result = await ReadMessagesAsync();
        if (result == null)
        {
            var messages = await DownloadMessagesAsync();
            await WriteMessagesAsync(messages);
        }
    }

    // private read/write/download methods here...
}

【讨论】:

  • 我假设,您的 ServiceMessageService 是一项服务?
  • 是的。以上只是直接写入 SO 的“元”。
【解决方案2】:

也许您将这些方法冷拆分为一些辅助类,并在您认为合适的视图模型中使用它们。或者,如果您已经有一些基本视图模型类(例如 INotifyPropertyChanged),您可以将它们移到那里,假设它们主要用于视图模型。

在异步之后摆脱 void。因为它是“一劳永逸”,所以您基本上启动了该方法,但无法控制它何时完成。在某些情况下它是可以的,但如果可以的话,请避免它。

【讨论】:

  • 嗯,将它们存储在帮助程序类中听起来像是一种解决方法——我对“本机”解决方案感兴趣。修复了 void 问题 - 实际上,我通常会尽量避免它。
猜你喜欢
  • 2014-06-21
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2023-02-06
  • 2021-08-14
  • 2012-06-28
  • 1970-01-01
相关资源
最近更新 更多