温馨提示:本文翻译自stackoverflow.com,查看原文请点击:c# - How can the scheduler of Task.Run be changed?
c# task unity3d

c# - 如何更改Task.Run的调度程序?

发布于 2020-04-23 15:11:22

我需要运行一些需要使用特定调度程序运行的任务,否则它们将失败,因为它们实例化的对象只能来自特定线程。

使用Task.Factory.StartNew效果很好,唯一的是语法有点麻烦。

因此,我想到了编写一种扩展方法的想法,该方法可以使我保留的简洁语法,Task.Run但可以指定另一个调度程序TaskScheduler.Default但是,我很难弄清楚如何编写这种扩展方法。

题:

Task.Run如果可能的话,如何更改要运行的调度程序

代码示例:

using System;
using System.Threading;
using System.Threading.Tasks;
using UnityEngine;

public class NewBehaviourScript : MonoBehaviour
{
    private async void Test()
    {
        // game objects can only be created from Unity main thread, get its scheduler

        var scheduler = TaskScheduler.FromCurrentSynchronizationContext();

        // 1. syntax using factory, works but is a bit cumbersome

        await Task.Factory.StartNew(
            () => new GameObject("test"),
            CancellationToken.None,
            TaskCreationOptions.None,
            scheduler
        );

        // 2. ideal syntax though it will fail since it'll run with the wrong scheduler

        await Task.Run(() => new GameObject("test"));

        // 3. ideal syntax but how to implement .Schedule method?

        await Task.Run(() => new GameObject("test")).Schedule(scheduler);
    }
}

扩展方式:

public static class Extensions
{
    public static Task<T> Schedule<T>(this Task<T> task, TaskScheduler scheduler)
    {
        // how, if possible at all to write this method?

        throw new NotImplementedException();
    }
}

查看更多

提问者
Aybe
被浏览
75
Stephen Cleary 2019-04-02 03:56

你想要的是TaskFactory只需创建一个您想要的TaskScheduler另外,您通常不希望使用默认选项设置。假设您正在使用与的任务await,则通常至少需要DenyChildAttach

var factory = new TaskFactory(CancellationToken.None,
    TaskCreationOptions.DenyChildAttach,
    TaskContinuationOptions.DenyChildAttach | TaskContinuationOptions.ExecuteSynchronously,
    scheduler);

一旦创建(一次),您就可以用于factory.StartNew排队工作,而不必每次都传递所有参数。