【问题标题】:How to create 300 stopwatches in C# more efficiently?如何更高效地在 C# 中创建 300 个秒表?
【发布时间】:2019-05-31 00:43:15
【问题描述】:

我正在创建一个需要测量用户查看对象时间的 UWP 应用程序。这个应用程序有大约 300 个对象来测量时间。为此,我们将使用大约 300 个计时器。为了实现这一点,我们将不得不单独创建 300 个秒表,这是非常低效的。

计时器在用户正在查看相应对象时启动,并在用户不再查看相应对象时停止。如果用户的目光再次注视在相应的对象上,当然计时器会再次启动。最后,秒表的所有时间都将保存到一个文件中。创建 300 个秒表需要为每个秒表编写一行新代码,这看起来效率不高。我试图通过使用 Enumerable.range 来自动化秒表创建过程,但到目前为止我还没有找到解决方案。

    /// <summary>
    /// All stopwatches for every word. In our real code we will have around 300 stopwatches.
    /// </summary>
    Stopwatch Stopwatch1 = new Stopwatch();
    Stopwatch Stopwatch2 = new Stopwatch();
    Stopwatch Stopwatch3 = new Stopwatch();
    Stopwatch Stopwatch4 = new Stopwatch();
    Stopwatch Stopwatch5 = new Stopwatch();
    Stopwatch Stopwatch6 = new Stopwatch();
    Stopwatch Stopwatch7 = new Stopwatch();
    Stopwatch Stopwatch8 = new Stopwatch();
    Stopwatch Stopwatch9 = new Stopwatch();
    Stopwatch Stopwatch10 = new Stopwatch();

【问题讨论】:

  • 为什么不创建一个List&lt;Stopwatch&gt;,然后使用循环来初始化所需的秒表数量?
  • 您只需要 1 个秒表和一个存储对象之前被查看的时间量的地方。然后在再次查看时增加它。
  • @Esko - 如果不能同时有多个锁

标签: c# uwp stopwatch


【解决方案1】:

只定义List&lt;Stopwatch&gt;()

var l = new List<Stopwatch>();
     for (var i = 0; i < 300; i++)
     {
         var w = Stopwatch.StartNew();

         w.Stop();
         l.Add(w);
     }

为了向您展示如何处理它,请参阅此示例

using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Threading;
using System.Threading.Tasks;

namespace ConsoleApplication1
{
    class Program
    {
        public static List<Stopwatch> sws = new List<Stopwatch>();
        public static List<Thread> threads = new List<Thread>();

        static void Main()
        {
            for (var i = 0; i < 300; i++)
            {               
                threads.Add(new Thread(Dummy));
                sws.Add(new Stopwatch());
            }

            for(int i = 0; i < 300; i++) sws[i].Start();

            new Thread( () => { for(int i = 0; i < 5; i++) threads[i].Start(i); }).Start();
            new Thread( () => { for(int i = 5; i < 10; i++) threads[i].Start(i); }).Start();
            new Thread( () => { for(int i = 10; i < 15; i++) threads[i].Start(i); }).Start();
            new Thread( () => { for(int i = 15; i < 20; i++) threads[i].Start(i); }).Start();
            new Thread( () => { for(int i = 20; i < 25; i++) threads[i].Start(i); }).Start();
            new Thread( () => { for(int i = 25; i < 30; i++) threads[i].Start(i); }).Start();
            new Thread( () => { for(int i = 30; i < 35; i++) threads[i].Start(i); }).Start();
            new Thread( () => { for(int i = 35; i < 40; i++) threads[i].Start(i); }).Start();

            Console.Read();
        }

        static void Dummy(object data)
        {
            int i = (int)data;
            Thread.Sleep(250); 
            sws[i].Stop();
            Console.WriteLine(sws[i].ElapsedMilliseconds.ToString());
        }
    }
}     

【讨论】:

    【解决方案2】:

    因此,首先您需要获取可用对象的列表。您可以使用以下代码创建一个通用字典,为您拥有的每个对象保留一个秒表。还有一个生成凝视调查的方法的示例实现。

    您仍然需要添加调用 start 和 stop 方法的代码。

    class Program
    {
        static Dictionary<object, Stopwatch> stopwatchesByObject;
    
        static void Main(string[] args)
        {
            List<object> objects = new List<object>();
    
            // now you have to fill the objects list...
    
            stopwatchesByObject = new Dictionary<object, Stopwatch>();
            foreach (var o in objects)
            {
                stopwatchesByObject.Add(o, new Stopwatch());
            }
        }
    
        // Call this method when the user starts gazing at object o
        static void StartGazingAt(object o)
        {
            stopwatchesByObject[o].Start();
        }
    
        // Call this method when the user stops gazing at object o
        static void StopGazingAt(object o)
        {
            stopwatchesByObject[o].Stop();
        }
    
        static void CreateStatistics()
        {
            StringBuilder sb = new StringBuilder();
            foreach (var entry in stopwatchesByObject)
            {
                sb.AppendLine($"Gazed at {entry.Key.ToString()} for {entry.Value.Elapsed.TotalSeconds} seconds.");
            }
            File.WriteAllText("c:\\temp\\statictics.txt", sb.ToString());
        }
    }
    

    【讨论】:

      【解决方案3】:

      我喜欢 Stefan Illners 的方法,并想添加一些 linq-magic,imo 非常简洁且可读性好。

      using System.Linq;
      
      var myListOfItemsToWatch = new List<object> { "foo", "bar", "baz" };
      var listOfStopwatches = myListOfItemsToWatch.ToDictionary(watchItem =>
              watchItem, i => new Stopwatch()
      );
      

      【讨论】:

        猜你喜欢
        • 2014-09-08
        • 1970-01-01
        • 1970-01-01
        • 2013-10-23
        • 1970-01-01
        • 2018-02-02
        • 1970-01-01
        • 1970-01-01
        • 2022-01-23
        相关资源
        最近更新 更多