Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/284.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/.net/21.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 调用数据库异步方法而不阻塞ui UWP的最佳实践_C#_.net_Uwp_Async Await - Fatal编程技术网

C# 调用数据库异步方法而不阻塞ui UWP的最佳实践

C# 调用数据库异步方法而不阻塞ui UWP的最佳实践,c#,.net,uwp,async-await,C#,.net,Uwp,Async Await,我有一个从SQLite数据库获取数据的应用程序。例如,我有一个类似以下的方法: public async Task<IEnumerable<TaskItem>> GetAllAsync() { using (var context = new NotesContext()) { try { return await context .Tasks

我有一个从SQLite数据库获取数据的应用程序。例如,我有一个类似以下的方法:

public async Task<IEnumerable<TaskItem>> GetAllAsync()
{
    using (var context = new NotesContext())
    {
        try
        {
            return await context
                .Tasks
                .ToListAsync();
        }
        catch (Exception)
        {
            return Enumerable.Empty<TaskItem>();
        }
    }
}
公共异步任务GetAllAsync() { 使用(var context=new NotesContext()) { 尝试 { 返回等待上下文 .任务 .ToListAsync(); } 捕获(例外) { 返回可枚举的.Empty(); } } } 我通过加载页面时绑定的命令调用此方法:

LoadedCommand = new RelayCommand<TaskItemViewModel>
            ((task) => GetAllTasksAsync(task));
LoadedCommand=newrelaycommand
((任务)=>GetAllTasksAsync(任务));
以及命令调用的方法:

public async void GetAllTasksAsync(TaskListItemViewModel taskList)
{
    ShowTaskListViewProgressRing = true;

    Tasks.Clear();
    TaskAutoSuggestBoxItems.Clear();

    var response = await _dataService
        .TaskService
        .GetAllAsync()
        .ConfigureAwait(false);

    var tasks = _mapper.Map<List<TaskItemViewModel>>(response);
    if (tasks.Count > 0)
    {
        var mainTasks = tasks
            .Where(t => t.ParentTask == null);
        mainTasks.ForEach(t =>
        {
            if (!tasks.Any(st => st.ParentTask == t.TaskID))
                return;
            t.SubTasks = new ObservableCollection<TaskItemViewModel>(
                tasks
                .Where(st => st.ParentTask == t.TaskID)
                .OrderBy(st => st.Position));
        });
        Tasks.AddRange(mainTasks);
        TaskAutoSuggestBoxItems
            .AddRange(_mapper.Map<IEnumerable<ItemModel>>(mainTasks.OrderBy(t => t.Title)));
    }
    CurrentTaskList = taskList;
    ShowTaskListViewProgressRing = false;
}
公共异步void GetAllTasksAsync(TaskListItemViewModel任务列表) { ShowTaskListViewProgressRing=true; 任务。清除(); TaskAutoSuggestBoxItems.Clear(); var response=wait\u数据服务 .任务服务 .GetAllAsync() .配置等待(错误); var tasks=\u mapper.Map(响应); 如果(tasks.Count>0) { var mainstasks=任务 。其中(t=>t.ParentTask==null); mainstasks.ForEach(t=> { 如果(!tasks.Any(st=>st.ParentTask==t.TaskID)) 回来 t、 子任务=新的可观察集合( 任务 .Where(st=>st.ParentTask==t.TaskID) .OrderBy(st=>st.Position)); }); Tasks.AddRange(主任务); TaskAutoSuggestBoxItems .AddRange(_mapper.Map(mainstasks.OrderBy(t=>t.Title)); } CurrentTaskList=任务列表; ShowTaskListViewProgressRing=false; } 如果我没有错,
GetAllTasksAsync
会被UI线程调用,但是当它到达
GetAllAsync().ConfigureAwait(false)
时,它会跳出上下文,然后
GetAllAsync
会在线程池上下文中运行,完成后会返回到UI线程并更新视图属性

这种方法正确吗

这种方法正确吗

捕捉异常并假装什么都没发生,这不是最佳做法:

catch (Exception)
{
    return Enumerable.Empty<TaskItem>();
}
另外,不返回值(如
GetAllTasksAsync
)的异步方法应返回
Task
,而不是
void

public async Task GetAllTasksAsync(TaskListItemViewModel taskList){ ... }
否则,当你打电话时,你就不能等待它了


您对捕获
SynchronizationContext
ConfigureAwait
的假设是正确的。

TaskAutoSuggestBoxItems
UI控件吗?@JohanP它是绑定到AutoSuggestBoxItemsSource的
ObservableCollection
属性,如果您不触摸其中的任何UI控件
GetAllTasksAsync
然后使用
configureAwait(false)
可以,否则由于未捕获上下文,您将获得异常,并且继续将在线程池线程上运行。@JohanP by ui controls在此上下文中它可能是绑定属性吗?如果这是正确的
任务
任务AutoSuggestBoxItems
被绑定到视图,那么应用程序应该崩溃吧?源属性与UI目标属性不同。您不能从后台线程触摸控件,但可以设置视图模型的源属性。您好,谢谢您,anwser,是的,我知道当前的try-catch不是最好的..,撇开它不谈,因此如果
GetAllTasksAsync
应该返回任务,那么我的命令看起来像
LoadedCommand=new RelayCommand(async(task)=>await GetAllTasksAsync(task));
在这种情况下,我为什么要等待GetAllTasksAsync?。根据@JohanP的评论,因为我正在触摸在
GetAllAsync()配置await(false)之后修改ui的属性
,应用程序应该崩溃,但在我的情况下,它不会崩溃。为什么设置视图模型的源属性会使应用程序崩溃?并且RelayCommand不是异步的。但是任何异步方法都应该返回任务。好的,当我调用
var response=wait\u dataService.TaskService.GetAllAsync().configurewait(false)时
ui线程仍然调用
GetAllAsync()
的内容,对吗?那么我应该在
返回等待上下文.Tasks.toListSync();
中添加
ConfigureAwait(false)
,还是在
任务.Run()中包装方法的内容?
GetAllAsync()
在调用线程上同步执行,直到它遇到等待。
异步
/
等待
不会导致创建任何新线程。如果有其他问题,请提出新问题。不要在注释字段中提出多个不同的问题。
public async Task GetAllTasksAsync(TaskListItemViewModel taskList){ ... }