.ToListAsync()vs .ToList()+ Task.Run

时间:2016-03-30 16:45:36

标签: c# wpf async-await

我有一个WPF应用程序。

数据从存储库传递到ViewModel。什么是检索数据的更好方法:

方法1:

在存储库中:

public List<LogDetail> GetLogsOfTypeForCase(int caseId, LoggType logType)
    {
        using (var ctx = new SidraEntitiesNoChangesDetection())
        {
            var logs = (from l in ctx.Loggs
                where l.log_fk_caseid == caseId && l.log_operation == logType.ToString()
                select new LogDetail()
                {
                    ColumnName = l.log_columnname,
                    DateAndTime = l.log_dateandtime,
                    IdentificationDetail = l.log_identificationDetail,
                    NewValue = l.log_new_value,
                    OldValue = l.log_old_value,
                    TableName = l.log_tablename,
                    UserCode = l.User.usr_code
                }).ToList();

            return logs;
        }
    }

在ViewModel中:

await Task.Run(
            () =>
            {
                if (false == this.CancellationTokenSource.IsCancellationRequested)
                {
                    this.CaseLogs = this.dataAdapter.GetLogsOfTypeForCase(this.CaseId, LoggType.S);
                }

            },
            this.CancellationTokenSource.Token
            );

方法2

在存储库中:

public async Task<List<LogDetail>> GetLogsOfTypeForCase(int caseId, LoggType logType)
    {
        using (var ctx = new SidraEntitiesNoChangesDetection())
        {
            var logs = await (from l in ctx.Loggs
                where l.log_fk_caseid == caseId && l.log_operation == logType.ToString()
                select new LogDetail()
                {
                    ColumnName = l.log_columnname,
                    DateAndTime = l.log_dateandtime,
                    IdentificationDetail = l.log_identificationDetail,
                    NewValue = l.log_new_value,
                    OldValue = l.log_old_value,
                    TableName = l.log_tablename,
                    UserCode = l.User.usr_code
                }).ToListAsync();

            return logs;
        }
    }

并在ViewModel中

protected override async void Load()
    {
           if (false == this.CancellationTokenSource.IsCancellationRequested)
           {
               this.CaseLogs = await this.dataAdapter.GetLogsOfTypeForCase(this.CaseId, LoggType.S);
           }
     }

从我所读到的,方法1将是首选,但有什么优势?

2 个答案:

答案 0 :(得分:11)

方法2是首选,因为它使用少一个线程。

它也可以(经过一些修改)正确支持取消:

public async Task<List<LogDetail>> GetLogsOfTypeForCase(int caseId, LoggType logType, CancellationToken token)
{
  ...
        }).ToListAsync(token);
  ...
}

protected override async void Load()
{
  this.CaseLogs = await this.dataAdapter.GetLogsOfTypeForCase(this.CaseId, LoggType.S, this.CancellationTokenSource.Token);
}

答案 1 :(得分:3)

方法2.这些方法的异步版本为您完成了所有“繁重的工作”,这就是它们的设计目标。 Task.Run()是一个繁重的过程调用,你需要自己处理所有潜在的错误和失败,你不需要这里的大锤,只需要一个轻量级的精加工锤。

我的意思是你试图创建框架已经为你做了什么,这是异步调用的意图,所以为什么不使用它们呢?