繁体   English   中英

用户界面被异步/等待阻止

[英]UI blocked with Async/Await

在这里的许多线程中都以某种方式提出了这个问题,但是我找不到我的情况的明确答案,我有一个简单的代码,一个Button ,一个Textbox和一个ButtonClickEventHandler ,尽管后者是Async ,但后者保持了UI阻塞,代码:

public partial class MainWindow : Window
    {
        public MainWindow()
        {
            InitializeComponent();
        }

        private async void ButtonBase_OnClick(object sender, RoutedEventArgs e)
        {
            Task t = new Task(() =>
            {
                for (int i = 0; i < 10000; i++)
                {
                    Dispatcher.Invoke((()=>
                    {
                        TextBox.Text += i.ToString();
                    }));
                }
            });
            t.Start();
            await t;

            //Something else
        }

    }

Xaml:

<Window x:Class="WpfApplication1.MainWindow"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    Title="MainWindow" Height="350" Width="525">
    <Grid>
        <Button Margin="180,10,185,277" x:Name="Button" Click="ButtonBase_OnClick">
           Ok
        </Button>
        <TextBox Margin="29,83,40,33" x:Name="TextBox"></TextBox>
    </Grid>
</Window>

首先,为什么会这样? 第二,我应该做的就是使UI始终保持正常运行而不会挂起,始终遵循此逻辑。

定义“已阻止”。 您发布的代码不会阻止UI。 但是,它肯定会使它保持真正的忙碌状态,这可能会使其看起来好像被阻止。 因此,即使不是真的,也可以出于所有实际目的将其阻止。

您基本上是在对GUI线程执行拒绝服务攻击。 您有一个紧密循环的辅助线程,该线程仅在GUI线程上继续执行操作。 不这样做,情况会好得多。

正如其他人指出的那样,如果您尝试过于频繁地更新UI,最终将阻止用户交互。

就您的代码而言,您应该使用Task.Run代替任务构造函数,并使用IProgress<T>代替Dispatcher.Invoke 我有一个IProgress<T>实现,可以为您处理限制 ,可以这样使用:

private async void ButtonBase_OnClick(object sender, RoutedEventArgs e)
{
  using (var progress = ObservableProgress<int>.CreateForUi(value => UpdateUi(value)))
  {
    await Task.Run(() => BackgroundOperation(progress));
  }

  ...
}

private static void UpdateUi(int progressUpdate)
{
  TextBox.Text += progressUpdate.ToString();
}

private static void BackgroundOperation(IProgress<int> progress)
{
  for (int i = 0; i < 10000; i++)
  {
    if (progress != null)
      progress.Update(i);
  }
}

无需人为延迟。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM