Await new Task( … ) : Task does not run?

前端 未结 4 1999
暖寄归人
暖寄归人 2021-01-02 02:20

A continuation of a question asked here :

In the aforementioned question I have the following function which returns an object of type Task (for incremental testing

相关标签:
4条回答
  • 2021-01-02 02:37

    To create a Task already started

    Try creating the task like this:

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

    To create a Task without starting it

    If you don't want the task started, just use new Task<object>(...) as you were using, but then you need to call Start() method on that task before awaiting it!

    [Reference]

    My recommendation

    Just make a method that returns the anonymous function, like this:

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

    Then get it and run it in a new Task whenever you need it (Also notice that I removed the async/await from the lambda expression, since you are putting it into a Task already):

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

    One advantage to this is that you can also call it without putting it into a Task:

    GetFunction()();
    
    0 讨论(0)
  • 2021-01-02 02:44

    OK, I think I've figured this out. Please examine this code:

    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!";
        }
    }
    
    0 讨论(0)
  • 2021-01-02 02:50

    You are stuck with a bad design there. I'll try to make something work for you under these constraints.

    The only way to delay start tasks is to use the Task.Start method. (You also can use RunSynchronously but that doesn't really make use of any of the tasks features. At this point the task becomes an unthreaded lazy object.

    So use the Task.Start method.

    await does not start tasks. It waits for tasks that already run. Therefore await new Task(() => { }) always freezes forever.

    Another problem here:

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

    When you start that task it will complete nearly instantly and Task.Result will hold another task - the one returned by the async lambda. I doubt this is what you want. Hard to make this work and I don't know what you need.

    This smells like the XY problem. Can you elaborate on what you want to accomplish? It feels like you have given yourself unnecessary constraints.

    0 讨论(0)
  • 2021-01-02 02:51

    You should never use the Task constructor (or Task.Start).

    I do not want this function to return a task that is already running ( that is IMPERATIVE ).

    So, you want to return some code that won't execute until you call it? That's a delegate, not a Task.

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

    When you're ready to execute it, call it just like any other delegate. Note that it returns a Task, so you can await the result:

    var func = GetInstance();
    // Delegate has not started executing yet
    var task = func();
    // Delegate has started executing
    var result = await task;
    // Delegate is done
    
    0 讨论(0)
提交回复
热议问题