简体   繁体   English

TaskScheduler.FromCurrentSynchronizationContext块UI

[英]TaskScheduler.FromCurrentSynchronizationContext block ui

I have this xaml 我有这个xaml

<Window x:Class="TestCloseWindow.MainWindow"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    Title="MainWindow" Width="500" Height="400">
<StackPanel>
    <TextBlock x:Name="Seconds"></TextBlock>
    <Button Content="fasdfd" Click="ButtonBase_OnClick"></Button>
</StackPanel>
</Window>

And this code 而这段代码

public partial class MainWindow
{
    public MainWindow()
    {
        InitializeComponent();
    }
    private async void ButtonBase_OnClick(object sender, RoutedEventArgs e)
    {
         await CountToTen();
    }

    private Task CountToTen()
    {
       return Task.Factory.StartNew
              (() =>
                  {
                      for (var i = 1; i <= 10; i++)
                      {
                        Seconds.Text = i.ToString(CultureInfo.InvariantCulture);
                        Task.Delay(1000).Wait();
                      }
                   }
                   , CancellationToken.None
                   , TaskCreationOptions.None
                   , TaskScheduler.FromCurrentSynchronizationContext()
              );
    }
}

In this code I use TaskScheduler.FromCurrentSynchronizationContext() in order to access UI from background Task. 在此代码中,我使用TaskScheduler.FromCurrentSynchronizationContext()以便从后台Task访问UI。
I expected that I can see how program count to ten, but instead of it I see blocked UI for 10 seconds and after 10 in TextBlock 我希望可以看到程序计数到十,但是相反,我在TextBlock中看到被阻止的UI持续10秒,然后是10秒

How can I fix it? 我该如何解决?

You are using a blocking call Wait in your CountToTen function. 您正在使用CountToTen函数中的阻塞调用Wait To fix this you will need to use await instead. 要解决此问题,您将需要使用await Which requires some other changes as well. 这还需要其他一些更改。

async private Task CountToTen()
{
    await Task.Factory.StartNew( async () =>
        {
            for (var i = 1; i <= 10; i++)
            {
                Seconds.Text = i.ToString(CultureInfo.InvariantCulture);
                //Task.Delay(1000).Wait();
                await Task.Delay(1000);
            }
        }, CancellationToken.None, TaskCreationOptions.None, TaskScheduler.FromCurrentSynchronizationContext());
}

By using StartNew with TaskScheduler.FromCurrentSynchronizationContext() , in this particular case, you're not really doing anything at all. 通过在TaskScheduler.FromCurrentSynchronizationContext()使用StartNew ,在这种特殊情况下,您根本没有做任何事情。 Since the entire task will be run in the UI thread it's no different from just executing it right there in line. 由于整个任务都将在UI线程中运行,因此与直接在其中执行任务没有什么不同。

The primary source of your problem is Task.Delay(1000).Wait(); 问题的主要来源是Task.Delay(1000).Wait(); . You're doing a blocking wait for a second, and you're doing that from the UI thread . 您正在等待一秒钟,然后在UI线程中进行 You can refactor the code to not do a blocking wait, and also remove the needless task creation. 您可以重构代码以不执行阻塞等待,也可以删除不必要的任务创建。 This is all you need: 这就是您所需要的:

private async void ButtonBase_OnClick(object sender, RoutedEventArgs e)
{
    for (var i = 1; i <= 10; i++)
    {
        Seconds.Text = i.ToString(CultureInfo.InvariantCulture);
        await Task.Delay(1000)
    }
}

暂无
暂无

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

相关问题 使用TaskScheduler.FromCurrentSynchronizationContext更新Task中的UI - update UI in Task using TaskScheduler.FromCurrentSynchronizationContext .NET中的TaskScheduler.FromCurrentSynchronizationContext() - TaskScheduler.FromCurrentSynchronizationContext() in .NET TaskScheduler.Current和TaskScheduler.FromCurrentSynchronizationContext()的区别? - TaskScheduler.Current and TaskScheduler.FromCurrentSynchronizationContext() difference? TaskScheduler.FromCurrentSynchronizationContext()是否表示该类的上下文? - Does TaskScheduler.FromCurrentSynchronizationContext() mean the context of the class? 我如何使用TaskScheduler.FromCurrentSynchronizationContext()解决后台线程异常上的UI更新 - how do i use TaskScheduler.FromCurrentSynchronizationContext() to solve UI update on background thread exception Task.ContinueWith(...,TaskScheduler.FromCurrentSynchronizationContext())在UI线程上运行的任何场景? - Any scenario where Task.ContinueWith(…, TaskScheduler.FromCurrentSynchronizationContext()) would *not* run on the UI thread? 为什么TaskScheduler.FromCurrentSynchronizationContext在Monotouch中不同步? - Why doesn't TaskScheduler.FromCurrentSynchronizationContext synchronize in Monotouch? 从工作线程调用TaskScheduler.FromCurrentSynchronizationContext异常 - TaskScheduler.FromCurrentSynchronizationContext exception when called from worker thread Async / Await等效于带有CancellationToken和TaskScheduler.FromCurrentSynchronizationContext()调度程序的.ContinueWith - Async/Await equivalent to .ContinueWith with CancellationToken and TaskScheduler.FromCurrentSynchronizationContext() scheduler 关于TaskScheduler.FromCurrentSynchronizationContext和Task.Factory.StartNew()的使用 - Regarding usage of TaskScheduler.FromCurrentSynchronizationContext & Task.Factory.StartNew()
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM