首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >等待自定义函数

等待自定义函数
EN

Stack Overflow用户
提问于 2014-02-21 12:24:58
回答 5查看 1.3K关注 0票数 3

我试图了解C#中的新异步功能,到目前为止,我注意到的最奇怪的事情是,每个异步特性的示例都有一个函数等待框架中定义的另一个异步函数,但它们都没有自定义代码。

例如,我想要的是从文本文件中的每一行创建一个对象,但是是异步的,这样UI线程就不会冻结:

代码语言:javascript
复制
async Task Read()
{
    string[] subjectStrings = File.ReadAllLines(filePath);
    for (int i = 0; i < subjectStrings.Length; i++)
    {
        Task<Subject> function = new Task<Subject>(code => new Subject((string)code), subjectStrings[i]);
        try
        {
            Subject subject = await function;
            subjects.Add(subject);
        }
        catch (Exception ex)
        {
            debugWriter.Write("Error in subject " + subjectStrings[i]);
            continue;
        }
    }
}

如您所见,我定义了一个任务,它基于文本文件中的一行创建一个新的Subject对象,然后等待此任务。如果我这样做,调试器就会到达await行,然后停止。据我所知,不再运行代码。

如果我使用的是旧的异步特性,我只需使用Task.ContinueWith()并添加一个回调lambda,将主题添加到列表中,并在路上。

所以我的问题是:

  1. 为什么这个代码不起作用?如何使不使用任何异步方法本身的自定义异步方法?
  2. 您应该如何使用异步方法?除非您处于异步函数中,否则不能使用await,而且不需要等待就不能调用异步方法,那么首先如何从同步方法调用该方法?
EN

回答 5

Stack Overflow用户

回答已采纳

发布于 2014-02-21 12:33:44

为什么这个代码不起作用?如何使不使用任何异步方法本身的自定义异步方法?

使用await Task.Runawait Task.Factory.StartNew创建和运行任务。调用new Task将创建一个尚未启动的任务。在大多数情况下,这是不必要的,但是您可以在以这种方式创建的任务上调用Start

您应该如何使用异步方法?除非您处于异步函数中,否则不能使用await,而且不需要等待就不能调用异步方法,那么首先如何从同步方法调用该方法呢?

适当的"root“异步调用取决于应用程序的类型:

  • 在控制台应用程序中:Wait在返回的Task上。
  • 在GUI应用程序中:使用async void事件处理程序。
  • 在ASP.NET MVC中:控制器可以返回Task
票数 1
EN

Stack Overflow用户

发布于 2014-02-21 12:27:04

你没有开始这个任务--所以它永远不会完成。

使用Task.Run而不是new Task,它将为您创建和启动任务。

请注意,您仍在同步读取该文件,这并不理想.如果您的Subject构造函数真的要花那么长时间才能完成,我会问它是否应该是一个构造函数。

票数 5
EN

Stack Overflow用户

发布于 2014-02-21 12:51:52

如何使不使用任何异步方法本身的自定义异步方法?

如果方法没有异步工作要做,那么它应该是同步的;它不应该是async

在核心部分,所有的async方法都归结为两种方法之一。它们要么通过类似Task.Run (不推荐使用库代码)将工作排队到线程池,要么通过TaskCompletionSource<T>Task.Factory.FromAsync等快捷方式执行真正的异步工作。

您应该如何使用异步方法?除非您处于异步函数中,否则不能使用await,而且不需要等待就不能调用异步方法,那么首先如何从同步方法调用该方法呢?

你没有。理想情况下,你应该一直都是async。控制台应用程序是这个规则的一个例外;它们必须有一个同步Main。但是对于WinForms、WPF、Silverlight、Windows、ASP.NET MVC、WebAPI、SignalR、iOS、Android和Windows应用程序以及单元测试,您应该一直使用异步。

您可以通过async和组合器(如Task.WhenAllTask.WhenAny )使用Task.WhenAll方法。这是使用async方法的最常见方法,但并不是唯一的方法;例如,您可以调用async方法并将其作为IObservable<T>使用。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/21934459

复制
相关文章

相似问题

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