繁体   English   中英

等待新任务<T> (...): 任务没有运行?

[英]Await new Task<T>( ... ) : Task does not run?

在这里提出的问题的延续:

在上述问题中,我有以下函数返回 Task 类型的对象(用于增量测试):

private static Task<object> GetInstance( ) {
    return new Task<object>( (Func<Task<object>>)(async ( ) => {
        await SimpleMessage.ShowAsync( "TEST" );
        return new object( );
    } ) );
}

当我调用await GetInstance( ); ,该函数被调用(并且我假设该任务被返回,因为没有抛出异常)但是任务只是坐在那里。

我只能猜测我当时做错了。

我不希望此函数返回已在运行的任务(即IMPERATIVE )。

如何异步运行此函数返回的任务?

创建一个已经开始的任务

尝试创建这样的任务:

Task.Factory.StartNew<object>((Func<Task<object>>) ...);

在不启动的情况下创建任务

如果您不希望任务开始,只需像您使用的那样使用new Task<object>(...) ,但是您需要在等待它之前对该任务调用Start()方法!

[参考]

我的推荐

只需创建一个返回匿名函数的方法,如下所示:

private static Func<object> GetFunction( ) {
    return (Func<object>)(( ) => {
        SimpleMessage.Show( "TEST" );
        return new object( );
    } );
}

然后获取它并在需要时在新Task运行它(另请注意,我从 lambda 表达式中删除了async/await ,因为您已经将其放入任务中):

Task.Factory.StartNew<object>(GetFunction());

这样做的一个优点是您也可以在不将其放入Task情况下调用它:

GetFunction()();

您永远不应该使用Task构造函数(或Task.Start )。

我不希望此函数返回已在运行的任务(即 IMPERATIVE )。

那么,您想返回一些在您调用之前不会执行的代码吗? 那是一个委托,而不是一个Task

private static Func<Task<object>> GetInstance()
{
  return async () =>
  {
    await SimpleMessage.ShowAsync("TEST");
    return new object();
  };
}

当您准备好执行它时,就像任何其他委托一样调用它。 请注意,它返回一个Task ,因此您可以await结果:

var func = GetInstance();
// Delegate has not started executing yet
var task = func();
// Delegate has started executing
var result = await task;
// Delegate is done

你被一个糟糕的设计困住了。 在这些限制下,我会尝试为您做一些事情。

延迟启动任务的唯一方法是使用Task.Start方法。 (您也可以使用RunSynchronously但这并没有真正利用任何任务功能。此时任务变成了一个无线程的惰性对象。

所以使用Task.Start方法。

await不启动任务。 它等待已经运行的任务。 因此await new Task(() => { })总是永远冻结。

这里的另一个问题:

return new Task<object>( (Func<Task<object>>)(async ( ) => {
    await SimpleMessage.ShowAsync( "TEST" );
    return new object( );
} ) );

当您开始该任务时,它几乎会立即完成并且Task.Result将保存另一个任务 - 由异步 lambda 返回的任务。 我怀疑这就是你想要的。 很难做到这一点,我不知道你需要什么。

这闻起来像 XY 问题。 你能详细说明你想完成什么吗? 感觉就像你给了自己不必要的限制。

好的,我想我已经弄清楚了。 请检查此代码:

class Program
{
    public static void Main(string[] args)
    {
        // Only RUN the task as needed.  FooGet 
        // still allows you to generalize your task.
        Task.Run(() =>
        {
            dynamic value = FooGet();

            value.RunSynchronously();

            Console.WriteLine(value.Result.Result.ToString());
        });

        while (true) Thread.Sleep(100);
    }

    private static Task<object> FooGet()
    {
        var task = new Task<object>(() => {
            return asyncBar();
        });

        return task;
    }

    private async static Task<object> asyncBar()
    {
        // do work!
        return "Hello, world!";
    }
}

暂无
暂无

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

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