【问题标题】:Static class conversion to a Async model静态类转换为异步模型
【发布时间】:2015-04-01 22:33:24
【问题描述】:

我有类——类骨架的核心如下:-

    class Pingdom
        {
            public static string Pingdom(List<Config> configtypes)
            {
                StringBuilder response = new StringBuilder();
                bool status = false;
                foreach(var c in configtypes)
                {
                    switch(c.Type)
                    {
                        case ConfigTypes.Database:
                            {
                                status = PingdomDB(c.ConnectionType);
                            }
                            break;
                        case ConfigTypes.API:
                            {
                                status = PingdomAPI(c.Endpoint);
                            }
                            break;
                    }
                }

                if (status)
                    return "Ping";
                else
                    return "No Ping";
            }
-------------------------------------------------------
.......................................................
} 

现在,我不希望类是静态的,我希望它能够以更健壮的方式采用更多异步方法。

本质上,获取配置列表,但异步处理它们。

如何采用这种方法?

【问题讨论】:

  • 这完全取决于PingdomDBPingdomAPI,您需要向我们展示您在这些函数中所做的事情,以便我们就如何将它们转换为异步调用提供任何建议。同样,现在您的代码仅返回列表中已处理的最后一项的状态,这是您真正想要的吗?

标签: c# .net c#-4.0 asynchronous async-await


【解决方案1】:
    class Pingdom {
        public static string PingMe(List<Config> configtypes)
        {
            bool status = true;
            List<Task> tasks2 = new List<Task>();
            foreach (Config config in configtypes)
            {
                if (config.Type == ConfigTypes.Database)
                {
                    tasks2.Add(Task.Factory.StartNew(() => { status = status && PingdomDB(config.ConnectionType); }, TaskCreationOptions.LongRunning));
                }
                else if (config.Type == ConfigTypes.API)
                {
                    tasks2.Add(Task.Factory.StartNew(() => { status = status && PingdomAPI(config.ConnectionType); }, TaskCreationOptions.LongRunning));
                }
            }
            Task.WaitAll(tasks2.ToArray(), System.Threading.Timeout.Infinite);
            if (status)
                return "Ping";
            else
                return "No Ping";
        }
    }

【讨论】:

  • 如果这些是长时间运行的任务,那么它将始终返回“Ping”。您应该等待任务完成或将状态作为任务的结果返回。由于每次调用 PingMe 只会创建 1 个任务,因此您不需要列表。
  • 抱歉,刚刚看到创建了多个任务。您仍然需要等待它们完成以计算状态的返回值。 var tasks2 = new List>(); ...... // 在 foreach 循环之后 await Task.WhenAll(tasks2); tasks2.ForEach(t => status = status && t.Result);返回状态? “Ping”:“无 Ping”;
  • 谢谢,Scott,我标记了它。谢谢,shr,我在传输代码时忘记包含 WaitAll。诅咒我的多动症:)
  • 这不是异步完成工作,而是并行完成工作,但仍然是同步的。
  • @FrancineDeGroodTaylor 是的,但 Servy 仍然是正确的。您仍在等待它完成 (Task.WaitAll)。实际上,使其异步会在某些层调用非线程支持的Task(例如异步/等待或TaskCompletionSource)或回调函数。代码仍然是同步的,您只是在并行执行同步操作。如果您返回 Task&lt;string&gt; 而不是字符串并使用 async/await 我会也许调用代码异步,但使用 Task.WaitAll 肯定不是。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-08-15
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多