Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/338.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 等待新任务<;T>;(…):任务未运行?_C#_Asynchronous_Async Await_Task - Fatal编程技术网

C# 等待新任务<;T>;(…):任务未运行?

C# 等待新任务<;T>;(…):任务未运行?,c#,asynchronous,async-await,task,C#,Asynchronous,Async Await,Task,继续提问: 在前面提到的问题中,我有以下函数返回Task类型的对象(用于增量测试): private静态任务GetInstance(){ 返回新任务((Func)(异步()=>{ 等待SimpleMessage.ShowAsync(“测试”); 返回新对象(); } ) ); } 当我调用等待GetInstance()时,函数被调用(我假设任务被返回,因为没有抛出异常),但任务就在那里 我只能猜测我做错了 我不希望此函数返回已在运行的任务(即命令式任务) 如何异步运行此函数返回的任务?创建已启

继续提问:

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

private静态任务GetInstance(){
返回新任务((Func)(异步()=>{
等待SimpleMessage.ShowAsync(“测试”);
返回新对象();
} ) );
}
当我调用
等待GetInstance()时,函数被调用(我假设任务被返回,因为没有抛出异常),但任务就在那里

我只能猜测我做错了

我不希望此函数返回已在运行的任务(即命令式任务)


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

创建已启动的任务

尝试按如下方式创建任务:

Task.Factory.StartNew<object>((Func<Task<object>>) ...);
private static Func<object> GetFunction( ) {
    return (Func<object>)(( ) => {
        SimpleMessage.Show( "TEST" );
        return new object( );
    } );
}
然后获取它,并在需要时在新的
任务中运行它(还要注意,我从lambda表达式中删除了
async/await
,因为您已经将其放入任务中了):


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

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!";
    }
}
类程序
{
公共静态void Main(字符串[]args)
{
//仅根据需要运行任务。FooGet
//仍然允许您概括您的任务。
Task.Run(()=>
{
动态值=FooGet();
value.RunSynchronously();
WriteLine(value.Result.Result.ToString());
});
while(真)线程。Sleep(100);
}
私有静态任务FooGet()
{
变量任务=新任务(()=>{
返回asyncBar();
});
返回任务;
}
专用异步静态任务asyncBar()
{
//干活儿!
返回“你好,世界!”;
}
}

您在那里遇到了一个糟糕的设计。在这些限制条件下,我会尽力为你做点事情

延迟启动任务的唯一方法是使用
Task.start
方法。(您也可以使用
同步运行
,但这并没有真正利用任何tasks功能。此时,task将成为一个无线程的惰性对象

因此,请使用
Task.Start
方法

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

这里还有一个问题:

return new Task<object>( (Func<Task<object>>)(async ( ) => {
    await SimpleMessage.ShowAsync( "TEST" );
    return new object( );
} ) );
返回新任务((Func)(async()=>{
等待SimpleMessage.ShowAsync(“测试”);
返回新对象();
} ) );
当您启动该任务时,它将几乎立即完成,
任务。Result
将保留另一个任务-异步lambda返回的任务。我怀疑这是您想要的。很难做到这一点,我不知道您需要什么


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

你永远不应该使用
任务
构造函数(或
任务.启动

我不希望此函数返回已在运行的任务(这是必需的)

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

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

您正在
等待
GetInstance
,这就是您的方法在那里等待的原因。它仍然是一个异步调用,因为线程可以被释放等待。我认为您将异步执行与多任务混合在一起。不清楚您在寻找什么,但也许?如果您实际上不知道,我不太理解为什么有必要这样做要开始获取实例,为什么要在该时间点调用
GetInstance()
?可能需要类似
Func
Lazy
的内容,因此可以推迟对
GetInstance()的调用
。我需要挂起对象而不运行它,因为该任务需要是一个可以取消的任务。我需要监视运行状态,以确定是否应该启动、取消、重新启动该对象,或者是否需要对用户的愚蠢行为大喊大叫……异步方法应该返回一个
任务
,该任务将完成ete在某个时间点没有被显式启动。我会维护
Func
实例,以便在需要时创建任务。等等-这不会启动任务吗?我需要返回任务而不启动它,然后再次启动它。我认为我对此非常明确(如果它没有启动任务,那么也可以,但这看起来像是它返回了一个已经在运行的任务…)当然,我假设这是您想要的,因为您正在等待它。否则,您应该调用task.start()?我修改了我的答案,希望它有助于解决我正在处理的情况的复杂性。这个问题超出了考虑范围(TL;DR:我做错了).然而,你的答案是创建任务并在不启动的情况下返回任务的正确方法。我认为最好将其纳入聊天中-不需要在此处转录战争与和平…现在我只需要找出如何在没有提示的情况下启动聊天会话…丁有一个发展…请查看你为什么要使用
dynamic
何时知道类型?出于某种原因,编译器无法识别嵌套任务。使用dynamic可以跳过编译器,并在运行时获取第二个任务结果。这是因为
FooGet()
正在创建并返回
任务,而不是
任务
(实际上是这样的)。谢谢-但这比你想象的要多。我需要这个任务,因为我需要它来支持任务取消和重新启动。我不想用我认为与当前问题无关的细节来解决这个问题。@Will:取消可以很好地解决这个问题。你说的“重新启动”到底是什么意思
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!";
    }
}
return new Task<object>( (Func<Task<object>>)(async ( ) => {
    await SimpleMessage.ShowAsync( "TEST" );
    return new object( );
} ) );
private static Func<Task<object>> GetInstance()
{
  return async () =>
  {
    await SimpleMessage.ShowAsync("TEST");
    return new object();
  };
}
var func = GetInstance();
// Delegate has not started executing yet
var task = func();
// Delegate has started executing
var result = await task;
// Delegate is done