【问题标题】:Convert Dictionary<string, Task<string>> to Dictionary<string, string>将 Dictionary<string, Task<string>> 转换为 Dictionary<string, string>
【发布时间】:2013-07-28 11:43:18
【问题描述】:

我不想使用foreach 循环两次,所以我尝试使用 LINQ,但不幸的是这不起作用:

return _etags.ToDictionary(item => item.Key, async item => await item.Value);

谁能告诉我应该怎么做才能改进我的代码,或者如何将Dictionary&lt;string, Task&lt;string&gt;&gt; 转换为Dictionary&lt;string, string&gt;?

这是我的代码:

private static async Task<Dictionary<string, string>> GetETagsAsync(List<string> feedsLink)
{
    var eTags = new Dictionary<string, string>(feedsLink.Count);
    System.Diagnostics.Stopwatch stopWatch = new System.Diagnostics.Stopwatch();
    stopWatch.Start();
    var _eTags = new Dictionary<string, Task<string>>(feedsLink.Count);
    eTags = new Dictionary<string, string>(feedsLink.Count);
    foreach (string feedLink in feedsLink)
    {
        if (Uri.IsWellFormedUriString(feedLink, UriKind.Absolute))
        {
            _eTags.Add(feedLink, GetETagAsync(feedLink));
        }
        else
        {
            throw new FormatException();
        }
        }
        foreach (KeyValuePair<string, Task<string>> eTag in _eTags)
        {
            eTags.Add(eTag.Key, await eTag.Value);
        }
        stopWatch.Stop();
        TimeSpan ts = stopWatch.Elapsed;

        return eTags;
    }

【问题讨论】:

  • 你试过.ToDictionary(item =&gt; item.Key, item =&gt; item.Value.Result);吗?

标签: c# linq dictionary microsoft-metro


【解决方案1】:

您不想在开始某些任务后抛出异常,最好先验证。

    private static async Task<Dictionary<string, string>> GetETagsAsync(List<string> feedsLink)
    {
        ValidateFeedsLinkFormat(feedsLink);

        var _eTags = feedsLink.ToDictionary(f => f, f => GetETagAsync(f));
        await TaskEx.WhenAll(_eTags.Values);

        var eTags = _eTags.ToDictionary(k => k.Key, k => k.Value.Result);

        return eTags;
    }

此代码启动所有任务,就像您的一样,但所有链接都只等待一次。 您不想在多个线程上使用 Stopwatch 的实例:来自MSDN:“不保证任何实例成员都是线程安全的。” 您可以使用Stopwatch.GetTimestamp(); 两次并比较结果。

【讨论】:

  • 非常感谢您的帮助,现在我的代码如下所示:pastebin.com/6Qnyn4j1 我还有一个问题。如您所见,我使用 GetETagAsync 方法,在此方法中如下所示:pastebin.com/p2TzC48x 我还验证了链接。我应该验证以前方法 (GetETagsAsync) 中的链接吗? GetETagAsync 写对了吗?
  • 我认为没有必要在 GetETagAsync 中验证链接,因为它是私有的,并且只能从您的代码中调用。如果您想要全部或全部都不需要,最好批量验证您的数据,但如果您想加载可以加载的内容,请在 GetETagAsync 中验证并使用 try/catch 块。
  • 抛出异常不是一个好习惯,也许你可以使用一个返回类来代替,或者至少指定所有的问题,而不是一个空的异常
  • 为什么不应该抛出异常?我是这样使用的:pastebin.com/0YYqQY74
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2014-10-22
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-07-19
相关资源
最近更新 更多