如何获得不计算在UI线程上执行任务 [英] How to get a task NOT to be executed on the UI thread

查看:162
本文介绍了如何获得不计算在UI线程上执行任务的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

下面的代码是一个代码,在实际应用中的简化。下面的问题是一个长期的工作将在UI线程中运行,而不是一个后台线程。

The following code is a simplification of a code in a real application. The problem below is that a long work will be ran in the UI thread, instead of a background thread.

    void Do()
    {
        Debug.Assert(this.Dispatcher.CheckAccess() == true);
        Task.Factory.StartNew(ShortUIWork, CancellationToken.None, TaskCreationOptions.None, TaskScheduler.FromCurrentSynchronizationContext());
    }

    void ShortUIWork()
    {
        Debug.Assert(this.Dispatcher.CheckAccess() == true);
        Task.Factory.StartNew(LongWork, TaskCreationOptions.LongRunning);
    }

    void LongWork()
    {
        Debug.Assert(this.Dispatcher.CheckAccess() == false);
        Thread.Sleep(1000);
    }



所以做()通常由UI上下文中调用。等是ShortUIWork,由的TaskScheduler所限定。然而,LongWork最终也被称为在UI线程,当然,块的用户界面。

So Do() is called normally from UI context. And so is ShortUIWork, as defined by the TaskScheduler. However, LongWork ends up called also in UI thread, which, of course, blocks the UI.

如何确保任务不会在UI线程跑?

How to ensure that a task is not ran in the UI thread?

推荐答案

LongRunning 仅仅是一个暗示,的TaskScheduler 。在该 SynchronizationContextTaskScheduler (由返回TaskScheduler.FromCurrentSynchronizationContext()),它显然忽略了提示的情况下。

LongRunning is merely a hint to the TaskScheduler. In the case of the SynchronizationContextTaskScheduler (as returned by TaskScheduler.FromCurrentSynchronizationContext()), it apparently ignores the hint.

在一方面,这似乎有悖常理。毕竟,如果任务长时间运行,这是不可能的,你希望它在UI线程上运行。在另一方面,根据MSDN:

On the one hand this seems counterintuitive. After all, if the task is long running, it's unlikely you want it to run on the UI thread. On the other hand, according to MSDN:

LongRunning - 指定一个任务将是一个长期运行,
粗粒度操作。它提供了一个暗示,那的TaskScheduler
超额可能有必要。

LongRunning - Specifies that a task will be a long-running, coarse-grained operation. It provides a hint to the TaskScheduler that oversubscription may be warranted.

由于UI线程不是一个线程池螺纹,没有超额(线程池饥饿),可能会发生,所以它有点有道理的提示将会对 SynchronizationContextTaskScheduler

Since the UI thread isn't a thread pool thread, no "oversubscription" (thread pool starvation) can occur, so it somewhat makes sense that the hint will have no effect for the SynchronizationContextTaskScheduler.

无论如何,你可以解决的问题,通过切换回默认任务调度程序:

Regardless, you can work around the issue by switching back to the default task scheduler:

void ShortUIWork()
{
    Debug.Assert(this.Dispatcher.CheckAccess() == true);
    Task.Factory.StartNew(LongWork, CancellationToken.None, TaskCreationOptions.LongRunning, TaskScheduler.Default);
}

这篇关于如何获得不计算在UI线程上执行任务的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆