【问题标题】:Compiler issues, struggling to call UI thread using Dispatcher.RunAsync() and return a value编译器问题,努力使用 Dispatcher.RunAsync() 调用 UI 线程并返回一个值
【发布时间】:2020-09-07 05:14:27
【问题描述】:

我在 UWP 中工作,需要调用 UI 线程,我通过将调用包装在 Dispatcher.RunAsync(...) 调用中来完成。下面的代码无法编译,因为:

转换为 void 返回委托的匿名函数不能 返回一个值

public async Task<RecentPlaysInfo> GetRecentPlayInfoAsync()
{
  await Windows.ApplicationModel.Core.CoreApplication.MainView.CoreWindow.Dispatcher.RunAsync(CoreDispatcherPriority.Normal, () =>
  {

    // This code is on the UI thread: 
    IReadOnlyList<MediaTimeRange> list = meCurrentMedia.MediaPlayer.PlaybackSession.GetPlayedRanges();

    for (int i = 0; i < list.Count; i++)
    {
      // if some criteria on list[i] is met: 
      return new RecentPlaysInfo(...);
    }

  });
}

简而言之:我尝试隔离 Dispatcher.RunAsync(...) 调用,以便它设置一个变量而不是转到 return,但执行似乎消失在黑洞中,所以我发现自己走上了这条道路,至少对于现在。

This thread 帮我去匿名化(下面的代码,注意额外的返回,以便所有路径都返回一个值)但现在编译错误是:

无法从 'System.Func' 转换为 'Windows.UI.Core.DispatchedHandler'

await Windows.ApplicationModel.Core.CoreApplication.MainView.CoreWindow.Dispatcher.RunAsync(CoreDispatcherPriority.Normal, (Func<RecentPlaysInfo>)(() =>
{

  // This code is on the UI thread: 
  IReadOnlyList<MediaTimeRange> list = meCurrentMedia.MediaPlayer.PlaybackSession.GetPlayedRanges();

  for (int i = 0; i < list.Count; i++)
  {
    // if some criteria on list[i] is met: 
    return new RecentPlaysInfo(...);
  }
                
  return null;
}));

我也读过this (kaffekopp's answer)this (Jon Skeet's answer),但我什至没有假装完全理解它们:(

我能够编写代码并调用 kaffekopp 修改后的 DispatchToUI(...) 方法,但这只是给了我:

无法从“System.Func”转换为“System.Action”

【问题讨论】:

  • 1. 我尝试隔离Dispatcher.RunAsync(...) 调用,以便它设置一个变量而不是返回... 这种方法必须有效。请分享您使用这种方法尝试过的代码。 2. 方法Dispatcher.RunAsync 的第二个参数被声明为不接受任何参数并返回void 的委托,因此您不能从中返回值。您帖子中的第一个编译器错误说明了这一点。

标签: c# uwp


【解决方案1】:

你的GetRecentPlayInfoAsync 会返回一个Task&lt;RecentPlaysInfo&gt;,所以你可以像下面那样做。

public async Task<RecentPlaysInfo> GetRecentPlayInfoAsync()
{
    RecentPlaysInfo info = new RecentPlaysInfo();
    await Windows.ApplicationModel.Core.CoreApplication.MainView.CoreWindow.Dispatcher.RunAsync(CoreDispatcherPriority.Normal, () =>
    {

        // This code is on the UI thread: 
        IReadOnlyList<MediaTimeRange> list = meCurrentMedia.MediaPlayer.PlaybackSession.GetPlayedRanges();

        for (int i = 0; i < list.Count; i++)
        {
            // if some criteria on list[i] is met: 
            info = new RecentPlaysInfo(...);
        }

    });

    return info;
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-12-07
    • 1970-01-01
    • 2012-04-01
    相关资源
    最近更新 更多