• 欢迎访问搞代码网站,推荐使用最新版火狐浏览器和Chrome浏览器访问本网站!
  • 如果您觉得本站非常有看点,那么赶紧使用Ctrl+D 收藏搞代码吧

C#中的多线程小试牛刀

c# 搞代码 4年前 (2022-01-09) 13次浏览 已收录 0个评论

前言

昨天在上班时浏览博问,发现了一个问题,虽然自己在 C# 多线程上没有怎么尝试过,看了几遍 CLR 中关于 线程的概念和讲解(后面三章)。也想拿来实践实践。问题定义是这样的:

对于多线程不是很懂,面试的时候遇到一个多线程的题,不会做,分享出来,懂的大佬指点一下,谢谢

建一个winform窗体,在窗体中放上一个开始按钮,一个停止按钮,一个文本框,在窗体中声明一个List类型的属性,点击开始按钮后开启10个线程,所有线程同时不间断的给List集合中添加1-10000之间的随机数,要求添加List集合中的数字不能重复,并且实时在文本框中显示集合的长度,当集合List的长度等于1000时自动停止所有线程,如果中途点击停止按钮也停止所有线程,点击开始又继续执行。

我其实没有完全实现了这位博问中提问的同学的需求,具体问题的来源可查看该地址 问题来源

开始尝试

刚拿到这个需求的时候,映入我脑海里的是 Task本文来源gao@daima#com搞(%代@#码@网&, Threadpool,Concurrent,和 Lock 等概念,接下来就是组装和编码的过程了,首先理一理头绪,

  • 生成随机数
  • 插入到 List 中,且不能重复
  • 开启多个线程同时插入。

首先是生成 随机数,使用 System.Random 类来生成伪随机数(这个其实性能和效率贼低,后面再叙述)

private int GenerateInt32Num()
{
 var num = random.Next(0, TOTAL_NUM);
 return num;
}

然后是插入到 List<Int32> 中的代码,判断是否 已经达到了 我们需要的 List 长度,如果已满足,则退出程序。

private void AddToList(int num)
{
 if (numList.Count == ENDNUM)
 {
 return;
 }

 numList.Add(num);
}

如果是个 单线程的,按照上面那样 while(true) 然后一直插入即可,可这个是个 多线程,那么需要如何处理呢?

我思考了一下,想到了之前在 CLR 中学到的 可以用 CancellationTokenSource 中的 Cancel 来通知 Task 来取消操作。所以现在的逻辑是,用线程池来实现多线程。然后传入 CancellationTokenSource.Token 来取消任务。

最后用 Task.WhanAny() 来获取到第一个到达此 Task 的 ID。

首先是建立 Task[] 的数组

internal void DoTheCompeteSecond()
{
 Task[] tasks = new Task[10];

 for (int i = 0; i < 10; ++i)
 {
 int num = i;
 tasks[i] = Task.Factory.StartNew(() => AddNumToList(num, cts), cts.Token);
 }

 Task.WaitAny(tasks);
}

然后 AddNumToList 方法是这样定义的,

private void AddNumToList(object state, CancellationTokenSource cts)
{-
 Console.WriteLine("This is the {0} thread,Current ThreadId={1}",
   state,
   Thread.CurrentThread.ManagedThreadId);

 while (!cts.Token.IsCancellationRequested)
 {
 if (GetTheListCount() == ENDNUM)
 {
  cts.Cancel();
  Console.WriteLine("Current Thread Id={0},Current Count={1}",
    Thread.CurrentThread.ManagedThreadId,
    GetTheListCount());

  break;
 }
 var insertNum = GenerateInt32Num();
 if (numList.Contains(insertNum))
 {
  insertNum = GenerateInt32Num();
 }

 AddToList(insertNum);
 }
}

看起来是没有什么问题的,运行了一下。得到了如下结果,


搞代码网(gaodaima.com)提供的所有资源部分来自互联网,如果有侵犯您的版权或其他权益,请说明详细缘由并提供版权或权益证明然后发送到邮箱[email protected],我们会在看到邮件的第一时间内为您处理,或直接联系QQ:872152909。本网站采用BY-NC-SA协议进行授权
转载请注明原文链接:C#中的多线程小试牛刀

喜欢 (0)
[搞代码]
分享 (0)
发表我的评论
取消评论

表情 贴图 加粗 删除线 居中 斜体 签到

Hi,您需要填写昵称和邮箱!

  • 昵称 (必填)
  • 邮箱 (必填)
  • 网址