返回Task <dictionary <string,string =“”>&gt; </dictionary <string,>类型的任务

时间:2013-06-08 10:48:46

标签: c# dictionary task async-await

我一直试图弄清楚如何返回类型为Task的数据而不是像这样的int,例如Task<Dictionary<string, string>>

我似乎发现的所有示例都显示返回Task<int>。这可以通过说return 42;来轻松完成。

我一直试图写的功能是这样的:

Task<Dictionary<string, string>> getDamaged()
{
    Task<Dictionary<string, string>> d = new Task<Dictionary<string, string>>();
    Dictionary<string, string> e = new Dictionary<string, string>();

    foreach (Building i in buildingArray)
    {
        if (Convert.ToInt32(i.efficiency) < 100)
        {
            e.Add(i.buildingID, i.buildingName);
            //d.Add(i.buildingID, i.buildingName);  // this does not work, either
        }
    }

我发现Task.FromResult method看起来很有希望,但进一步的调查似乎表明TResult作为一项完整的任务对我来说听起来不一定像你可以await。< / p>

有关如何使其正常工作的任何想法?

更新

这个方法的意思是我试图从我的UI线程卸载工作以保持我的UI响应。这是我第一次尝试使用带有.net4.5的visual studio 2012来尝试这样做。上面的代码我是从内存中写的。我将发布我一直尝试的实际代码,并注释掉失败的尝试。

真正让我感到困惑的一个部分是,如果我返回一个int,如果我的返回类型是任务,但是如果我尝试使用字典,我会得到一个关于无法隐式将字典转换为任务的错误

    private Task<Dictionary<string, string>> GetDamagedBuildings()
    {
        //Task<Dictionary<string, string>> damagedBuildings = new Task<Dictionary<string,string>>();
        Dictionary<string, string> d = new Dictionary<string, string>();
        foreach (ButtonPlanetMap i in buttonArray)
        {
            //Dictionary<string, string> d = new Dictionary<string,string>();
            if (Convert.ToInt32(i.efficiency) < 100)
            {
                d.Add(i.buildingID.ToString(), i.buildingName);
                //(Dictionary<string, string>)damagedBuildings.
            }
        }
        //damagedBuildings = Cast d;
        //return damagedBuildings;
        return d;
    }

3 个答案:

答案 0 :(得分:5)

int没有什么特别之处,你可以用同样的方法从你的方法中返回Dictionary

你应该做什么取决于你的方法为什么会返回Task

  1. 如果您没有充分理由退回Task,请不要返回Task,直接返回Dictionary
  2. 如果您要返回Task来完成界面,但实际上并不想使您的方法异步,Task.FromResult()是一个很好的解决方案。您可以使用以下内容:return Task.FromResult(dictionary);。此类Task仍然可以await,只是await会立即完成。
  3. 如果您返回Task,因为您的方法是CPU密集型而您想在后台线程上执行它,那么您应该使用Task.Run()

    return Task.Run(() =>
    {
        var dictionary = new Dictionary<string, string>();
        …
        return dictionary;
    });
    

    但这样做通常不是一个好主意,请参阅Should I expose asynchronous wrappers for synchronous methods?

答案 1 :(得分:2)

使用Task.FromResult意味着您的方法同步运行,然后返回一个已完成的任务,这可能不是您想要的(尽管您可以等待已完成的任务)。

您可以使用TaskFactory.StartNew开始新任务。如果您使用的是.Net 4.5,则可以使用Task.Run而不是TaskFactory.StartNew使用一些常见的默认参数。

Task<Dictionary<string,string>> GetDamaged()
{
    return Task.Factory.StartNew(() => {
        Dictionary <string, string> e = new Dictionary<string, string>();

        foreach(Building i in buildingArray)
        {
            if(Convert.ToInt32(i.efficiency) < 100)
            {
                e.Add(i.buildingID, i.buildingName);
            }
        }

        return e;
    }
}

答案 2 :(得分:0)

当您的async方法的返回值为Task<int>时,您的代码应返回int。同样,当您的async方法的返回值为Task<Dictionary<string, string>>时,您的代码应返回Dictionary<string, string>

async Task<Dictionary<string, string>> getDamagedAsync()
{
    Dictionary<string, string> e = new Dictionary<string, string>();

    var buildingArray = await GetBuildingsAsync();
    foreach (Building i in buildingArray)
    {
        if (Convert.ToInt32(i.efficiency) < 100)
        {
            e.Add(i.buildingID, i.buildingName);
        }
    }

    return e;
}