【问题标题】:What must I do to make my methods awaitable?我必须怎么做才能让我的方法可以等待?
【发布时间】:2012-11-22 18:56:35
【问题描述】:

如何滚动我自己的异步等待方法?

我发现在某些情况下编写异步方法很容易:

private async Task TestGeo()
{
    Geolocator geo = new Geolocator();
    Geoposition pos = await geo.GetGeopositionAsync();
    double dLat = pos.Coordinate.Latitude;
    double dLong = pos.Coordinate.Latitude;
}

...但遗憾的是,也看到并非所有方法都可以随意异步化;也就是说:这不起作用:

private async Task TestAsyncAwait()
{
    int i = await TaSLs_Classes.TASLsUtils.GetZoomSettingForDistance(5);
}

...它阻止了我的编译错误,“无法等待 int”;设计时的提示同样告诉我,“type 'int' is not awaitable”

我也试过这个,结果是一样的:

    Task<int> i = await TaSLs_Classes.TASLsUtils.GetZoomSettingForDistance(5);

我必须怎么做才能让我的方法可以等待?

更新

正如 Linebacker 和 S. Cleary 所指出的(与曾经在 KNBR 上的那只猫有任何关系吗?),这是可行的:

int i = await Task.Run(() => TaSLs_Classes.TASLsUtils.GetZoomSettingForDistance(5));

...也就是说,它编译——但它从不“移动”。

在运行时,它告诉我应该“等待”对 TestAsyncAwait() 的 CALL,但如果我这样做,它根本不会编译...

【问题讨论】:

  • int i = await Task.Run(() =&gt; TaSLs_Classes.TASLsUtils.GetZoomSettingForDistance(5));
  • 我推荐你阅读TAP
  • 那么 Lambda 不仅是必要的,而且现在是强制性的?至少到目前为止,我一直将它们视为聪明绝顶的把戏。
  • 你确定想要让它可以等待吗?
  • 不,我只是在做实验——我想知道如何让方法可以等待,这样我就可以“一直做到奶牛回家”或“甚至不用考虑(太多)考虑”我需要。

标签: c# windows-8 async-await windows-store-apps


【解决方案1】:

你只需要返回一个等待。 Task/Task&lt;TResult&gt;是常见的选择;可以使用Task.Run(在后台线程上执行代码)或TaskCompletionSource&lt;T&gt;(包装异步事件)来创建Tasks。

阅读Task-Based Asynchronous Pattern了解更多信息。

【讨论】:

    【解决方案2】:

    你的方法

    private async Task TestAsyncAwait()
    {
        int i = await TaSLs_Classes.TASLsUtils.GetZoomSettingForDistance(5);
    }
    

    应该这样写

    private async Task TestAsyncAwait()
    {
        Task<int> t = new Task<int>(() =>
        {
            return TaSLs_Classes.TASLsUtils.GetZoomSettingForDistance(5);
        });
        t.Start();
        await t;
    }
    

    如果需要返回int,替换Task类型:

    private async Task<int> TestAsyncAwait()
    {
        Task<int> t = new Task<int>(() =>
        {
            return TaSLs_Classes.TASLsUtils.GetZoomSettingForDistance(5);
        });
        t.Start();
        return await t;
    }
    

    【讨论】:

    • 链接失效
    【解决方案3】:
    var something = Task<int>.Factory.StartNew(() => 0);
    something.Wait();
    int number = something.Result;
    

    【讨论】:

    • 投反对票,因为 OP 显然试图异步执行此操作
    • 感谢 aaronburro 添加不赞成票的解释。这太罕见了。
    • 稀有实用。
    【解决方案4】:

    您需要消耗等待的回报或返回Task&lt;Type of await call&gt;

    1. private async Task<Geoposition> TestGeo()
      {
          Geolocator geo = new Geolocator();
          return await geo.GetGeopositionAsync();
      }
      
    2. private async Task<int> TestAsyncAwait()
      {
          return await TaSLs_Classes.TASLsUtils.GetZoomSettingForDistance(5);
      }
      

    【讨论】:

    • 问题是关于#2,对于#2,错误提示“Type 'int' is not awaitable”
    猜你喜欢
    • 2013-02-22
    • 1970-01-01
    • 2014-01-12
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多