首页 > 解决方案 > 通用windows平台后台运行巨大进程时如何制作交互式UI?

问题描述

目前正在从事清洁架构的项目。我想制作一个交互式 UI,即使后端正在运行一个巨大的进程。

  private async void SaveButton_Click(object sender, RoutedEventArgs e)
    {
        if (addFriendsViewModel.isValidMailId(mailId.Text))
        {
          isFriendAddedSuccessfully = await 
          addFriendsViewModel.AddUserInDB(mailId.Text);

            if (isFriendAddedSuccessfully)
                showSuccessDialog();
            else
                showErrorDialog();
        }
     }

这是我的点击事件监听器。

 public async Task<bool> AddUserInDB(string friendMailId)
    { 
        if (isValidUser(friendMailId) && !isAlreadyFriends())
        {
           addFriendUseCase = new AddFriendsUseCase(new FriendsDetail() {   
                             friendsUserId = friendsUserId ,userID = 1 });
            addFriendUseCase.SetCallBack<AddFriendCallBack>(this);
            for(int i=1;i<1000000000;i++)
            {
                Debug.WriteLine("hi there" + i);
            }
            addFriendUseCase.Execute();
            return true;
        }
        else
        {
            return false;
        }
    }

在上面的代码中,for 循环是一个巨大的示例过程。

即使正在运行巨大的进程(for循环),我也想制作交互式用户界面。但是当控件到达时,我的 ui 不是交互式的。

标签: c#uwpasync-await

解决方案


您标记一个方法的事实实际上async并没有使它在另一个线程本身上异步运行 - 这是关于async/await. 事实上,该async/await功能的工作方式是代码一直在同一个线程上执行,直到遇到“真正的”异步调用——这可能是一个 I/O 绑定await操作(例如文件、网络等) . 并且在此 I/O 操作之后立即再次返回到原​​始线程(除非ConfigureAwait(false)被使用)。在您的情况下,该方法根本不包含任何内容await,因此它将完全在 UI 线程上运行,并且仅在完成后返回。

如果要在另一个线程上运行操作,可以使用Task.Run

await Task.Run(()=> DoSomething());

这不会使您的 UI 直接显示进度更新,但它会在操作运行时保持响应。如果您想显示进度更新,您应该在一个类中实现该操作,该类event将报告进度并订阅它。但是,您需要确保再次在 UI 线程上运行事件处理程序 - 使用Dispatcher. 例如,查看此博客文章了解更多详细信息。


推荐阅读