C# 返回类型为Task的任务<;字典<;字符串,字符串>&燃气轮机;

C# 返回类型为Task的任务<;字典<;字符串,字符串>&燃气轮机;,c#,dictionary,task,async-await,C#,Dictionary,Task,Async Await,我一直在试图找出如何在类型Task中返回数据,而不是像这样的int,例如,Task 我找到的所有示例都显示返回一个任务。通过说return42,这很容易做到 我一直试图编写的函数的工作原理如下: Task<Dictionary<string, string>> getDamaged() { Task<Dictionary<string, string>> d = new Task<Dictionary<string, strin

我一直在试图找出如何在类型Task中返回数据,而不是像这样的int,例如,
Task

我找到的所有示例都显示返回一个
任务
。通过说
return42,这很容易做到

我一直试图编写的函数的工作原理如下:

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
将意味着您的方法同步运行,然后返回已完成的任务,这可能不是您想要的(尽管您可以等待已完成的任务)

您可以使用启动新任务。如果您使用的是.Net 4.5,则可以使用它,它使用带有一些常见默认参数的
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;
    }
}
Task GetDamaged()
{
返回Task.Factory.StartNew(()=>{
字典e=新字典();
foreach(Building Array中的一号楼)
{
if(转换为32(即效率)<100)
{
e、 添加(i.buildingID,i.buildingName);
}
}
返回e;
}
}

async
方法的返回值为
Task
时,代码应返回
int
。同样,当
async
方法的返回值为
Task
时,代码应返回
字典

异步任务getDamagedAsync() { 字典e=新字典(); var buildingArray=等待GetBuildingAsync(); foreach(Building Array中的一号楼) { if(转换为32(即效率)<100) { e、 添加(i.buildingID,i.buildingName); } } 返回e; }
int
没有什么特别之处,您可以用完全相同的方式从方法返回
词典

具体应该做什么取决于方法返回任务的原因

  • 如果您没有很好的理由返回
    任务
    ,请不要返回
    任务
    ,直接返回
    词典
  • 如果您返回一个
    任务
    来完成一个接口,但实际上不想使方法异步,
    任务.FromResult()
    是一个很好的解决方案。您可以这样使用它:
    返回任务.FromResult(字典)
    。这样的
    任务
    仍然可以
    等待
    完成,只是
    等待
    会立即完成
  • 如果您返回一个
    任务
    ,因为您的方法是CPU密集型的,并且您希望在后台线程上执行它,那么您应该使用
    Task.Run()

    返回任务。运行(()=>
    {
    var dictionary=newdictionary();
    …
    返回字典;
    });
    
    但是这样做通常不是一个好主意,明白吗


  • 将函数标记为
    async
    。为什么它需要成为
    任务
    ?您的方法是完全同步的,那么为什么要麻烦呢?您不能只返回
    字典
    ?Kirill Shlenskiy我打算从另一个方法中等待此方法。就我对async和Wait工作的理解而言,我们可以使用此方法关键字async你必须在函数中的某个地方有一个wait。而wait只在调用另一个返回任务的方法时才起作用。如果我的理解不正确,请纠正我。@Jazzeroki:你的问题相当混乱;Lee和我的回答都是基于不同的假设。Svick有最好的答案,涵盖了这两个方面请允许我谦恭地建议对您的答案进行两项改进:1.它不应包含任何“也不起作用”的内容。作为一个解决方案,所有这些都应该起作用。:)2。最好只关注
    Task.Factory.StartNew(…)
    部分,而不是复制和粘贴问题的代码(另请参见我的第一点);现在,我们必须将问题代码与答案代码进行比较,以了解使其起作用的确切区别。(当然,不难理解。)这假设方法是异步的,我在问题中没有看到任何迹象。是的。我假设是
    async
    ,因为op提到他们理解
    Task
    方法如何返回
    int
    值。请确认我没有使用async关键字。这是经过深思熟虑的,因为我对异步的理解是,如果没有等待,该方法仍然只是同步运行。Stephen显然,我在第一次尝试解决这一问题时,就尝试了您建议的方法,Visual Studio 2012给了我一个错误,说我无法将字典隐式转换为任务。@Jazzeroki:async
    关键字是将
    t
    转换为
    任务
    。Stephen显然感谢我的答案需要。感谢大家提供的所有其他反馈和提示。我打算使此方法能够使用async,因为它是由ui调用的,我正在尝试从ui线程中卸载尽可能多的工作,以保持其响应性。我没有像您使用lambda表达式和匿名方法那样尝试过。这是个不错的主意,我可能会在我正在从事的项目的其他领域使用它。真正让我头疼的是,如果返回类型是task,visualstudion2012将允许我使用return和int,但如果我尝试只返回一个字典,它会给我一个隐式转换错误。这就是为什么我想弄明白如何将字典转换为Task@Jazzeroki您的
    int
    方法是否标记为
    async
    ?这可以解释这种差异。此外,MS对WinRT的指导方针是,需要超过50毫秒的方法应该是异步的。你的方法需要50毫秒以上吗?如果不是,那么可能不值得将其设置为
    async
    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;
        }
    }
    
    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;
    }
    
    return Task.Run(() =>
    {
        var dictionary = new Dictionary<string, string>();
        …
        return dictionary;
    });