C#线程问题和最佳实践

这是我第一次在C#应用程序中使用线程。 基本上它是一个应用程序,它检查列表中的一堆网站是死还是活。

这是我第一次尝试使用multithreading

public void StartThread(string URL,int no) { Thread newThread = new Thread(() => { BeginInvoke(new Action(() => richTextBox1.Text += "Thread " + no + " Running" + Environment.NewLine)); bool b = ping(URL); if (b == true) { BeginInvoke(new Action(() => richTextBox2.Text += "Okay" + Environment.NewLine)); } else { return; } }); newThread.Start(); } 

我正在使用上面的函数来创建新线程,并且每个线程都在循环内创建。

foreach(网站中的字符串网站){StartThread(site,i); 我++; //柜台}

由于我是初学者,我几乎没有问题。

  1. 代码工作正常,但我不确定这是否是最佳解决方案
  2. 有时线程运行得很好但有时Threads不会从方法ping()返回任何值,它检查主机并返回true,如果它在线使用WebRequest。 通常吗?
  3. 如果我要求用户指定他需要使用的线程数,我如何在这些线程中平均分配工作?
  4. 他们是一个优雅的方式,我跟踪线程的状态,(死/活)? 我目前使用rocess.GetCurrentProcess().Threads.Count;

1)你的解决方案没问题。 Thread类已被Task类部分取代,如果您正在编写新代码,则可以使用它。 .NET 4.5中还有一些全新的东西叫做await。但是,参见4)。

2)如果网站已经死亡,您的ping方法可能会崩溃。 您可以向我们展示该方法的代码。

4)线程类很好,因为您可以根据您的要求使用ThreadState属性轻松检查线程状态 – 只需创建一个List ,将您的线程放入其中,然后逐个启动它们。

3)如果要从输入加载线程数并均匀分配工作,请将任务放入队列中(可以使用已建议的ConcurrentQueue)并让线程从队列中加载URL。 示例代码:

你初始化一切

 void initialize(){ ConcurrentQueue queue = new ConcurrentQueue(); foreach(string url in websites) { queue.Enqueue(url); } //and the threads List threads = new List(); for (int i = 0; i < threadCountFromTheUser; i++) { threads.Add(new Thread(work)); }} //work method void work() { while (!queue.IsEmpty) { string url; bool fetchedUrl = queue.TryDequeue(out url); if (fetchedUrl) ping(url); } } 

然后跑

 foreach (Thread t in threads) { t.Start(); } 

代码未经测试

为每个请求启动一个新线程是低效的…你可能希望拥有固定数量的工作线程(因此可以在cpu的每个核心上运行)

看一下ConcurrentQueue类,它将为您提供一个线程安全的先进先出队列,您可以在其中排队您的请求,让每个工作线程将请求出列,处理它等等,直到队列为止是空的 …

请注意,您可能无法从主GUI线程之外的其他线程调用GUI上的控件…查看ISynchronizeInvoke接口,它可以帮助您确定是否需要通过调用另一个线程来处理跨线程情况

你应该考虑.Net ThreadPool 。 但是,它通常不适合执行时间超过大约秒的线程。

另请参见: 并行编程模式:使用.NET Framework了解和应用并行模式4