繁体   English   中英

在C#中,当并行运行异步任务时,最后一个将永远运行一次

[英]In C#, when running async tasks in parallel, the last one runs again and again forever

从服务器读取xml时,我必须运行多个数据库插入,因此为了有效地做到这一点,我试图并行运行处理函数。

这可以很好地工作,但是由于某种原因,最后一个任务会一次又一次地永远运行,即使它的调用不止一次(我在调试器中彻底检查了它)。

有问题的代码:

    static string sLast = "";
    static string sReadElement = "";
    static Dictionary<string, string> dctEvent;
    ...
    static void Main(string[] args)
    {
        XmlReader xrReader = XmlReader.Create(GetDataStream(), new XmlReaderSettings() { DtdProcessing = DtdProcessing.Parse });

        try
        {
            Dictionary<string, Task> dctEventTasks = new Dictionary<string, Task>();
            while (xrReader.Read())
            {
                switch (xrReader.NodeType)
                {
                    case XmlNodeType.Element:
                        switch (xrReader.Name)
                        {
                            case "event":
                                dctEvent = new Dictionary<string, string>();
                                break;
                            ...
                            default:
                                sReadElement = xrReader.Name;
                                break;
                        }

                        break;

                    case XmlNodeType.Text:
                        ...
                        break;

                    case XmlNodeType.EndElement:
                        switch (xrReader.Name)
                        {
                            ...
                            case "event":
                                if (!dctEvent.ContainsKey(dctEvent["gamenumber"]))
                                {
                                    Func<Task> func = async () =>  await HandleEvent(dctEvent, lstParticipants, lstPeriods);
                                    dctEventTasks.Add(dctEvent["gamenumber"], Task.Run(func));
                                }
                                break;
                        }
                        break;
                }
            }

            Log("Last: " + sLast);
            Task.WhenAll(dctEventTasks.Values);
        }
        catch (Exception ex)
        {
            Log(ex.Message);
        }

        Console.ReadKey();
    }

    private static async Task HandleEvent(Dictionary<string, string> dctEvent, List<Dictionary<string, string>> lstParticipants, List<Dictionary<string, string>> lstPeriods)
    {
        ...
        Log("Finished handling event: " + dctEvent["gamenumber"]);
    }

我解决了 问题在于dctEvent,lstParticiapnts和lstPeriods是静态的,并且在主while循环的每次运行中都共享。 因此,当编辑集合时,对于并行运行的其他异步方法,结果将发生变化。 解决的办法是像这样克隆集合:

                            case "event":
                                if (!dctEventTasks.ContainsKey(dctEvent["gamenumber"]))
                                {
                                    var cdctEvent = dctEvent.ToDictionary(entry => entry.Key,
                                           entry => entry.Value);
                                    var clstParticipants = lstParticipants.ToList();
                                    var clstPeriods = lstPeriods.ToList();
                                    Func<Task> func = async () =>  await HandleEvent(cdctEvent, clstParticipants, clstPeriods);
                                    dctEventTasks.Add(dctEvent["gamenumber"], Task.Run(func));
                                }
                                break;

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM