C#线程问题和;最佳做法

C#线程问题和;最佳做法,c#,multithreading,C#,Multithreading,这是我第一次在C#应用程序中使用线程。基本上,它是一个应用程序,可以检查列表中的一堆网站,无论是死的还是活的 这是我第一次尝试使用多线程 public void StartThread(string URL,int no) { Thread newThread = new Thread(() => { BeginInvoke(new Action(() => richTextBox1.Text += "Threa

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

这是我第一次尝试使用多线程

    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); i++;//计数器}

因为我是初学者,所以我没有什么问题

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

  • 为每个请求旋转一个新线程是低效的。。。您可能希望有固定数量的工作线程(这样就可以在cpu的每个核心上运行一个)

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

    请注意,您可能不会从主GUI线程以外的其他线程调用GUI上的控件。。。请看<代码> IsSimuleEngule>代码>界面,它可以帮助您判断是否需要通过调用另一个线程

    来处理跨线程情况。但是,它通常不适用于执行时间超过秒的线程

    另见: 1)您的解决方案还可以。Thread类已被该类部分取代,如果您正在编写新代码,则可以使用该类。在.NET4.5中还有一个全新的功能,名为.NET 4.5

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

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

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

    你初始化了一切

    void initialize(){
    ConcurrentQueue<string> queue = new ConcurrentQueue<string>();
    foreach(string url in websites)
    {
        queue.Enqueue(url);
    }
    //and the threads
    List<Thread> threads = new List<Thread>();
    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);
        }
    }
    

    未使用MessageBox测试代码

    ?它将阻止UI线程,直到您将其关闭!另一种方法是将它记录下来,或者将它放入listview/listbox中。@David:我不知道。谢谢现在,我将结果添加到文本框中。稍后我会将其添加到列表框中。非常感谢您的详细回复。我在初始化ConcurrentQueue时遇到问题,因为我一初始化它就会产生错误。非泛型类型ThreadTest.form1.ConcurrentQueue不能与类型参数一起使用。很抱歉,我没有理解您的意思。台词是什么?如果你指的是声明,那么这些声明应该是全局声明的,对吗?。。否则,如果它在函数中,其他方法将如何读取它们并与之交互?对不起,我的错误。我认为您的代码没有问题,您从哪里得到错误?就在这里,
    ConcurrentQueue queue=new ConcurrentQueue()。它会产生以下错误:非泛型类型ThreadTest.form1.ConcurrentQueue不能与类型参数一起使用。听起来您在其他地方声明了一个名为ConcurrentQueue的类型,您在其他地方有类似的类型吗?
    
    foreach (Thread t in threads)
    {
        t.Start();
    }