TaskCompletionSource in async function

I have a function like this:

public async Task<bool> DoSomething()
{
   var tcs = new TaskCompletionSource<bool>();

   // Here is the problem. I need to keep this line because I wait on something asynchronously, but the function must return bool and I can't just return tcs.Task
   while(something)
      await Task.Delay(100);

   someobject.somevent += () => {
      // do some sht
      tcs.SetResult(true);
   }

   // it doesn't work
   return tcs.Task;
}

This is just fake code, but I have a real situation when I need it. I want to keep DoSomething asynchronous, but I also want to keep Task.Delay / Sleep in it. How to do this in a not-async function that returns only a task?

UPDATE:

THIS WORK:

class Program
    {
        static TaskCompletionSource<bool> tcs = new TaskCompletionSource<bool>();


        static Task<bool> Test()
        {
           // tcs = new TaskCompletionSource<bool>();
            Task.Factory.StartNew(() =>
            {
                Console.WriteLine("Waiting...");
                Thread.Sleep(5000);
                Console.WriteLine("Setting result");
                if(tcs.TrySetResult(true))
                    Console.WriteLine("Result has been set");


            });

            return tcs.Task;
        }

        static async Task Test2()
        {
            Console.WriteLine("Starting awaiting");
            var result = await Test();
            Console.WriteLine(result.ToString());
        }

        static void Main(string[] args)
        {


            Test2();

            Console.ReadKey(false);

        }
    }

and it is not

static async Task<bool> Test()
{
   // tcs = new TaskCompletionSource<bool>();
    Task.Factory.StartNew(() =>
    {
        Console.WriteLine("Waiting...");
        Thread.Sleep(5000);
        Console.WriteLine("Setting result");
        if(tcs.TrySetResult(true))
            Console.WriteLine("Result has been set");


    });


    return await tcs.Task;
}

worse, I tested it in my windows forms application and expected tcs.Task caused a weird crash when exiting System.Threading .... dll

+4
source share
2 answers

All this will turn out much more elegant if you highlight the logic of turning the event Taskinto your own method.

public static Task<bool> WhenSomeEvent(this SomeObject someobject)
{
    var tcs = new TaskCompletionSource<bool>();
    Action handler = null;
    handler = () =>
    {
        tcs.SetResult(true);
        someobject.SomeEvent -= handler;
    };
    someobject.SomeEvent += handler;
    return tcs.Task;
}

-, Task:

public async Task<bool> DoSomething()
{
    while(something)
        await Task.Delay(100);

    return await someobject.WhenSomeEvent();
}
+7

( , ), :

public async Task<bool> DoSomething()
{
   var tcs = new TaskCompletionSource<bool>();
   someobject.somevent += () => {
      // do some sht
      tcs.SetResult(true);
   }

   return await tcs.Task;
}
+6

Source: https://habr.com/ru/post/1627052/


All Articles