Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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

I have a WPF application.

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

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

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?

like image 261
Alex Albu Avatar asked Mar 30 '16 16:03

Alex Albu


People also ask

What is the difference between ToList and ToListAsync?

ToListAsync() is ToList asynchronous. Asynchronous methods can be executed without crashing the application's main thread. Eg in a WinForms application, do not hang the GUI on long operations.

What is ToList Async?

ToListAsync(IQueryable, CancellationToken)Creates a List<T> from an IQueryable by enumerating it asynchronously.


2 Answers

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

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);
}
like image 148
Stephen Cleary Avatar answered Sep 25 '22 19:09

Stephen Cleary


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.

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?

like image 26
CJ1 Avatar answered Sep 22 '22 19:09

CJ1