none
How to create (and not start) async task with lambda RRS feed

  • Question

  • Consider the following code snipped:

    using System.Threading.Tasks;
    
    namespace Tester
    {
        public static class TestClass
        {
            public static async Task<byte[]> DoSomethingAsync()
            {
                int a = 1;
                int b = 2;
                Task<byte[]> myIOBoundTask = GetIOBoundTask(a, b);
                Task timeoutTask = Task.Delay(150);
                Task firstFinishedTask = await Task.WhenAny(myIOBoundTask, timeoutTask);
                if (firstFinishedTask == myIOBoundTask) return await myIOBoundTask;
                else return null;
            }
            private static async Task<byte[]> GetIOBoundTask(int a, int b)
            {
                MyType other = new MyType(a, b);
                return await other.ProcessIOBoundOperationAsync();
            }
        }
    }
    
    This works fine (the shown code is not actual, only descriptive of my problem), however, I would like to specify myIOBoundTask as a lambda or similar to avoid creation of a separate private method.
    How to do this?

    Sunday, November 26, 2017 7:01 PM

All replies

  • Thanks

    I am not totally unknown to lambdas (except VB lambdas because syntax very much matters here).
    Could you please be more specific (and C# if possible)?

    I have tried with something like:

            public static async Task<byte[]> DoSomethingAsync()
            {
                int a = 1;
                int b = 2;
                Task<byte[]> myIOBoundTask = new Task<byte[]>( async () =>
                {
                    MyType other = new MyType(a, b);
                    return await other.ProcessIOBoundOperationAsync();
                });
                Task timeoutTask = Task.Delay(150);
                Task firstFinishedTask = await Task.WhenAny(myIOBoundTask, timeoutTask);
                if (firstFinishedTask == myIOBoundTask) return await myIOBoundTask;
                else return null;
            }
    
    But the compiler complains with:
    CS4010 Cannot convert async lambda expression to delegate type 'Func<byte[]>'. An async lambda expression may return void, Task or Task<T>, none of which are convertible to 'Func<byte[]>'

    Sunday, November 26, 2017 9:11 PM

  • I am not totally unknown to lambdas (except VB lambdas because syntax very much matters here).
    Could you please be more specific (and C# if possible)?


    This is not the C# forum, but a forum for .Net Framework Common Language Runtime Internals and Architecture (VB, C++, F# and C#)

    If your question is mainly about C# than ask your question in that forum.

    http://social.msdn.microsoft.com/Forums/en-US/csharpgeneral


    Success
    Cor

    Monday, November 27, 2017 12:24 AM
  • Hi EuroEager,

    According to your description, MyType is defined by yourself. Hence I could not test the code you provided.

    Normally, if you use lambda for method, the format is right. But the type is not suitable. Please provide the details about your code like ProcessIOBoundOperationAsync and so on.

    Here is a simple code for your reference. I could not test that I could not make sure it works well for your code.

      Func<Task> myIOBoundTask = async () =>
                {
                    MyType other = MyType(a, b);
                    await other.ProcessIOBoundOperationAsync();
                };

    Best Regards,

    Wendy


    MSDN Community Support
    Please remember to click "Mark as Answer" the responses that resolved your issue, and to click "Unmark as Answer" if not. This can be beneficial to other community members reading this thread. If you have any compliments or complaints to MSDN Support, feel free to contact MSDNFSF@microsoft.com.

    Tuesday, November 28, 2017 7:42 AM
    Moderator
  • Thanks Wendy

    Your proposal worked fine, but I had to Invoke the Func which seems a bit odd to me (as not very well skilled on TPL etc.).

    However, Task.Run (with a lambda and without the Func keyword) also solves the "problem" seemingly just fine.
    And, yes, I know that Task.Run should only be used for CPU bound code, but I do not see any difference from my original way of getting the task by a method anyway, this way I got rid of the method which was my goal.

    B.t.w. I stated my problem wrongly at the beginning, I thought that calling a method which returns a task does not actually start the task, but it does so indeed.

    If this is flawless I consider the issue as solved.

    Tuesday, November 28, 2017 10:29 AM