1

我的一位学生要求我创建一个解释多线程的示例。我想出了这个伪示例,它将产生线程,这些线程将随机循环次数并在循环时休眠。我通过一个使用 Guid 来识别每个线程的字典来跟踪这些线程。

字典可用于用于监视这些线程并可能“杀死”它们的页面。

这看起来合理吗:

public class LongProcess
    {
        public static Dictionary<Guid, LongProcess> Monitor = new Dictionary<Guid, LongProcess>();

        public Guid Id { get; set; }

        public int Iterations { get; set; }//number of loops

        public int SleepFactor { get; set; }//rest period while looping

        public int CompletedIterations { get; set; }//number of completed loops


        void Process()
        {
            for(var i = 0 ; i < Iterations; i++)
            {
                Thread.Sleep(1000*SleepFactor);
                SleepFactor = new Random(DateTime.Now.Millisecond).Next(1, 5);
                this.CompletedIterations++;
            }
        }

        public void Start()
        {
            Monitor.Add(Id, this);
            var thread = new Thread(new ThreadStart(Process));
            thread.Start();
        }
    }

下面是如何使用这个类:

    var id = Guid.NewGuid();
    var rnd = new Random(DateTime.Now.Millisecond);
    var process = new LongProcess
                      {
                          Iterations = rnd.Next(5, 20),
                          SleepFactor = rnd.Next(1, 5),
                          Id = id
                      };
    process.Start();

任何想法,将不胜感激。

4

3 回答 3

4

只要所有调用都process.Start发生在同一个线程上,您就不需要锁定字典,因为它不会在LongProcess类内部启动的后台线程中访问。这意味着:您的类LongProcess不是线程安全的,但在您当前的代码中这不是问题。
为了安全起见并避免锁定,您可以使用ConcurrentDictionary<TKey, TValue>.NET4 中的新版本。

于 2012-04-18T12:42:33.893 回答
2

其他人已经回答了关于字典锁的问题,我同意他们的看法。

我要改变的一件事是属性的设置器。它们目前是公开的,这意味着您可以在线程迭代时修改底层值,这不是一个很好的 api 设计。

我会在类中添加一个构造函数来获取你想要的参数并将设置器设为私有,这样任何人都不会意外更改你的类上的值,从而导致奇怪的结果。

于 2012-04-18T13:20:56.883 回答
0

您将需要锁定字典,它将被多个线程访问,或者您可以使用 System.Collections.Concurrent.ConcurrentDictionary,它在设计上是线程安全的

于 2012-04-18T12:43:46.960 回答