Entity Framework Core + SQlite. Asynchronous requests are actually synchronous

I have a WPF program, and I'm trying to use EF Core with SQLite, and I found some weird behavior. Even if I call the async method, for example ToArrayAsync () or SaveChangesAsync (), it returns the already completed task. Thus, this means that the operation was performed synchronously.

It seems that there should be some flag in the EF or SQLite connection that controls the execution of sync / async, but I did not find it.

I used this code for tests:

using (var context = new TestDbContext())
{
    //I have about 10000 records here.
    var task = context.Users.ToListAsync();
    if (task.IsCompleted && task.Result != null)
    {
        // It is always comes here.
    }
    await task;
}
+6
source share
1 answer

, SQLite ADO.NET(DbConnection, DbCommand) . Async, , . , DbConnection.OpenAsync:

public virtual Task OpenAsync(CancellationToken cancellationToken)
{
  TaskCompletionSource<object> completionSource = new TaskCompletionSource<object>();
  if (cancellationToken.IsCancellationRequested)
  {
    completionSource.SetCanceled();
  }
  else
  {
    try
    {
      this.Open();
      completionSource.SetResult((object) null);
    }
    catch (Exception ex)
    {
      completionSource.SetException(ex);
    }
  }
  return (Task) completionSource.Task;
}

, , .

Async DbCommand: TaskCompletionSource, Task.FromResult.

SQLiteCommand , - , . , () ExecuteReaderAsync:

/// <summary>
/// Executes the <see cref="P:Microsoft.Data.Sqlite.SqliteCommand.CommandText" /> asynchronously against the database and returns a data reader.
/// </summary>
/// <param name="behavior">A description of query results and its effect on the database.</param>
/// <param name="cancellationToken">The token to monitor for cancellation requests.</param>
/// <returns>A task representing the asynchronous operation.</returns>
/// <remarks>
/// SQLite does not support asynchronous execution. Use write-ahead logging instead.
/// </remarks>
/// <seealso href="http://sqlite.org/wal.html">Write-Ahead Logging</seealso>
public virtual Task<SqliteDataReader> ExecuteReaderAsync(CommandBehavior behavior, CancellationToken cancellationToken)
{
  cancellationToken.ThrowIfCancellationRequested();
  return Task.FromResult<SqliteDataReader>(this.ExecuteReader(behavior));
}

- SqlConnection SqlCommand () , OpenAsync ExecuteReaderAsync, sql , .

, , , SQLite.

WPF, , , async\await, . Task.Run .

+3

Source: https://habr.com/ru/post/1015973/


All Articles