首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >异步函数中的TaskCompletionSource

异步函数中的TaskCompletionSource
EN

Stack Overflow用户
提问于 2016-02-03 00:20:47
回答 2查看 13K关注 0票数 10

我有这样一个函数:

代码语言:javascript
复制
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;
}

这只是一个虚假的代码,但我有真正的情况下,我需要它。我想让DoSomething保持异步,但我也想让Task.Delay/睡眠在其中。如何在仅返回任务的非异步函数中做到这一点?

更新:

这是可行的:

代码语言:javascript
复制
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);

        }
    }

但这并不是

代码语言:javascript
复制
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;
}

更糟糕的是,我已经在我的windows窗体应用程序中测试了它,等待来自System.Threading....dll的tcs.Task导致奇怪的崩溃

EN

回答 2

Stack Overflow用户

发布于 2016-02-03 00:31:35

如果我理解正确(这很棘手,因为你的问题不那么容易理解),你可以按如下方式重申:

代码语言:javascript
复制
public async Task<bool> DoSomething()
{
   var tcs = new TaskCompletionSource<bool>();
   someobject.somevent += () => {
      // do some sht
      tcs.SetResult(true);
   }

   return await tcs.Task;
}
票数 15
EN

Stack Overflow用户

发布于 2016-02-03 00:56:54

如果你将事件触发转换成Task的逻辑转换成它自己的方法,整个事情就会变得更加优雅。

代码语言:javascript
复制
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的所有逻辑

代码语言:javascript
复制
public async Task<bool> DoSomething()
{
    while(something)
        await Task.Delay(100);

    return await someobject.WhenSomeEvent();
}
票数 13
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/35158546

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档