无法从'System.Threading.Tasks.Task'转换为'System.Collections.Generic.Dictionary <string,string>'

use*_*374 1 .net c# multithreading task-parallel-library async-await

我相信我可能只是语法错误,但我想要做的是创建一个在另一个任务完成后运行的任务.

我在列表中为每个100的数组创建了一个任务.它启动一个新线程将该数组传递给一个方法.该方法在完成时返回字典.我正在尝试创建一个在方法完成后运行的任务,它将返回的字典传递给另一个执行更多工作的方法.

static void Main(string[] args)
    {
        try
        {
            stopwatch = new Stopwatch();
            stopwatch.Start();
            while (true)
            {
                startDownload();
            }
        }
        catch (Exception ex)
        {
            Console.WriteLine(ex.Message);
        }
    }

public static async void startDownload()
    {
        try
        {

            DateTime currentDay = DateTime.Now;

            if (Helper.holidays.Contains(currentDay) == false)
            {
                List<string> markets = new List<string>() { "amex", "global", "nasdaq", "nyse" };

                Parallel.ForEach(markets, async market =>
                {
                    try
                    {

                        IEnumerable<string> symbolList = Helper.getStockSymbols(market);
                        var historicalGroups = symbolList.Select((x, i) => new { x, i })
                          .GroupBy(x => x.i / 100)
                          .Select(g => g.Select(x => x.x).ToArray());

                        Task<Dictionary<string, string>>[] historicalTasks =
                                                           historicalGroups.Select(x => Task.Run(() =>
                                                           Downloads.getHistoricalStockData(x, market)))
                                                                    .ToArray();

                        Dictionary<string, string>[] historcalStockResults = await
                                                                             Task.WhenAll(historicalTasks);

                        foreach (var dictionary in historcalStockResults)
                        {
                            Downloads.updateSymbolsInDB(dictionary);
                        }
                    }
                    catch (Exception ex)
                    {
                        Console.WriteLine(ex.Message);
                    }
                });

                await Task.Delay(TimeSpan.FromHours(24));
            }
        }
        catch (Exception ex)
        {
            Console.WriteLine(ex.Message);
        }
    }
Run Code Online (Sandbox Code Playgroud)

Yuv*_*kov 5

ContinueWith如果你已经在使用,我会建议不要使用await.原因是您在代码中最终得到的冗长.

相反,await尽可能使用.代码最终如下:

var historicalGroups = symbolList
                       .Select((x, i) => new { x, i })
                       .GroupBy(x => x.i / 100)
                       .Select(g => g.Select(x => x.x).ToArray());

var historicalTasks = historicalGroups.Select(x => Task.Run(() => 
                                       Downloads.getHistoricalStockData(x, market)))
                                      .ToArray();

var historcalStockResults = await Task.WhenAll(historicalTasks);

foreach (var dictionary in historcalStockResults)
{
    Downloads.updateSymbolsInDB(dictionary);
}
Run Code Online (Sandbox Code Playgroud)

注意使用Task.Run而不是Task.Factory.StartNew.你应该使用它.更多关于这一点

编辑:

如果您需要每24小时执行一次此代码,请添加一个Task.Delayawait在其上:

await Task.Delay(TimeSpan.FromHours(24));
Run Code Online (Sandbox Code Playgroud)

编辑2:

你的代码是不工作的原因是因为startDownloadasync void和你不等待就可以了.因此,你的while循环不断不管你的迭代Task.Delay.

因为您在控制台应用程序中,所以不能await因为Main方法不能同步.因此,要解决的是,改变startDownloadasync Task不是async voidWait上返回Task.请注意,使用Wait几乎从未被使用,预计为特殊场景(如一个控制台应用程序内运行时):

public async Task StartDownload()
Run Code Online (Sandbox Code Playgroud)

然后

while (true)
{
    StartDownload().Wait();
}
Run Code Online (Sandbox Code Playgroud)

还要注意的是混合Parallel.Foreachasync-await并非总是最好的主意.您可以在Parallel.ForEach嵌套等待中阅读更多内容