wpf .ToListAsync() 与 .ToList() + Task.Run

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/36314926/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-13 13:44:07  来源:igfitidea点击:

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

c#wpfasync-await

提问by Alex Albu

I have a WPF application.

我有一个 WPF 应用程序。

The data is brought from the repository to the ViewModel. What would be the better way to retrieve the data:

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

Method 1:

方法一:

In Repository:

在存储库中:

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;
        }
    }

In ViewModel:

在视图模型中:

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

            },
            this.CancellationTokenSource.Token
            );

or Method 2

方法二

In Repository:

在存储库中:

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;
        }
    }

and in ViewModel

并在 ViewModel 中

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

From what I have read, Method 1 would be preferred, but what be the advantages?

从我读到的内容来看,方法 1 是首选,但有什么优点?

回答by Stephen Cleary

Method 2 is preferable, because it uses one less thread.

方法 2 更可取,因为它少用了一个线程。

It also can (with some modifications) properly support cancellation:

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

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);
}

回答by CJ1

Method 2. The Async versions of these methods do all the "heavy lifting" for you, that was what they were designed for. Task.Run() is a heavy process call, you are required to handle all the potential errors and failures yourself, you don't need a sledge hammer here, just a light weight finishing hammer.

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

By this I mean that you are trying to create what the framework has already done for you, this is where Async calls were meant to be used so why not just use them?

我的意思是您正在尝试创建框架已经为您完成的工作,这是使用异步调用的地方,为什么不直接使用它们呢?