none
C# 多线程问题。 RRS feed

  • 问题

  • 例如,有一千个HTTP请求,你们会选择是用单线程还是多线程。
    如果是多线程的话,应该如何写了,
     static void Main(string[] args)
            {
                for (int i = 0; i < 5; i++)
                {
                    Thread td = new Thread(xx);
                    td.Start();
                }
            }
    //如果加上同步机制就失去多线程意义了。
            static void xx()
            {
                for (int i = 1; i < 1000; i++)
                {
                    Console.WriteLine("HTTP请求位置{0}",i);
                }
            }
    
    //请各位老师,朋友们给个解案方案;感谢你们无私的奉献!
    


    2012年9月18日 3:24

答案

  • 你的思路是对的,不过我建议你应该设置一个信号,以便当某个后台线程完成1000个信号处理的时候给予反馈。何况你现在在使用的是控制台,后台线程将会在主线程结束之后自动结束。因此可能主线程结束之后后台线程还没有执行完任务就Over。

    大致如下:

    public class MainTest
    {
    static void xx(object obj)
            {
                AutoEventReset reset = (AutoEventReset)obj;
                for (int i = 1; i < 1000; i++)
                {
                    //处理复杂的任务……
    } reset.Set(); } static void Main(string[] args) { AutoEventReset[]flags = new AutoEventReset[5]; for (int i = 0; i < 5; i++) { int temp = i; flags[temp] = new AutoEventReset(false); Thread td = new Thread(new ParameterizedThreadStart(xx)); td.IsBackGround=true; td.Start(flags[temp]); } WaitHandler.WaitAll(flags); } }

    下载MSDN桌面工具(Vista,Win7)
    我的博客园
    慈善点击,点击此处

    • 已标记为答案 JJAVEN 2012年9月18日 9:50
    2012年9月18日 6:16
    版主
  • 那你可以这样做:

    1)把全部准备请求的Url存入一个List<string>中,假定名称为urls。

    2)给N个线程平均分配任务(urls.Count/N,如果无法除尽设法给某个线程多一点的任务)。

    3)然后这N个线程通过for循环启动,每次创建一个线程;分别处理这个List中特定范围内的Url请求。

    4)使用我上面的方法,设置信号AutoEventReset,报告主程序各个子进程都完成任务,输出结果。


    下载MSDN桌面工具(Vista,Win7)
    我的博客园
    慈善点击,点击此处

    • 已标记为答案 JJAVEN 2012年9月18日 9:49
    2012年9月18日 8:08
    版主
  • 都是可以的。

    Task可以实现多线程,同时还可以实现异步操作。

    简单做法:

    Task t = new Task(()=>
    {
       //你的东西……
    });
    
    t.Start();

    注意:后台线程!


    下载MSDN桌面工具(Vista,Win7)
    我的博客园
    慈善点击,点击此处

    • 已标记为答案 JJAVEN 2012年9月18日 9:49
    2012年9月18日 8:23
    版主
  • 你这是设置每一个线程执行1000遍任务。假设总共有3000个任务,需要3个线程,每一个线程执行1000个任务,那么:

    //假设存在着3000个url的List,那么: for (int i = 0; i < 3; i++) { int temp = i; Task t=new Task ( ()=> { for(int j=temp*1000;j<temp*1000+1000;++j) { //处理你自己的事情…… } } ) t.Start(); }

    注意加上信号机制!


    下载MSDN桌面工具(Vista,Win7)
    我的博客园
    慈善点击,点击此处

    • 已标记为答案 JJAVEN 2012年9月18日 9:49
    2012年9月18日 9:09
    版主
  • 感谢版本对我的无私奉献,本人还有一个疑问就是,这种线程数量是不是跟thraed线程数量是一样。有一个最大数的。

    最大数?我知道线程池有,线程应该没有限制吧?

    下载MSDN桌面工具(Vista,Win7)
    我的博客园
    慈善点击,点击此处


    2012年9月19日 1:22
    版主

全部回复

  • 你的思路是对的,不过我建议你应该设置一个信号,以便当某个后台线程完成1000个信号处理的时候给予反馈。何况你现在在使用的是控制台,后台线程将会在主线程结束之后自动结束。因此可能主线程结束之后后台线程还没有执行完任务就Over。

    大致如下:

    public class MainTest
    {
    static void xx(object obj)
            {
                AutoEventReset reset = (AutoEventReset)obj;
                for (int i = 1; i < 1000; i++)
                {
                    //处理复杂的任务……
    } reset.Set(); } static void Main(string[] args) { AutoEventReset[]flags = new AutoEventReset[5]; for (int i = 0; i < 5; i++) { int temp = i; flags[temp] = new AutoEventReset(false); Thread td = new Thread(new ParameterizedThreadStart(xx)); td.IsBackGround=true; td.Start(flags[temp]); } WaitHandler.WaitAll(flags); } }

    下载MSDN桌面工具(Vista,Win7)
    我的博客园
    慈善点击,点击此处

    • 已标记为答案 JJAVEN 2012年9月18日 9:50
    2012年9月18日 6:16
    版主
  • 感谢版主提醒,我目前的问题.

    例用一千个网址。我需要多线程去请求完成,而线程数量我想采用自定方式。1-1000这样,自定或许是5或许是10。

    不重复的请求网址,请问我应该用什么方法,Thread、ThreadPool、Task。

    请供各位老师们提供一下简单的方法。目前我使用Threadpool可以做到。


                for (int i = 0; i < 1000; i++)
                {
                    
                    ThreadPool.QueueUserWorkItem(new WaitCallback(xx),i);
                }
    但这种方法不利于管理控制。


    2012年9月18日 7:56
  • 那你可以这样做:

    1)把全部准备请求的Url存入一个List<string>中,假定名称为urls。

    2)给N个线程平均分配任务(urls.Count/N,如果无法除尽设法给某个线程多一点的任务)。

    3)然后这N个线程通过for循环启动,每次创建一个线程;分别处理这个List中特定范围内的Url请求。

    4)使用我上面的方法,设置信号AutoEventReset,报告主程序各个子进程都完成任务,输出结果。


    下载MSDN桌面工具(Vista,Win7)
    我的博客园
    慈善点击,点击此处

    • 已标记为答案 JJAVEN 2012年9月18日 9:49
    2012年9月18日 8:08
    版主
  • 那你可以这样做:

    1)把全部准备请求的Url存入一个List<string>中,假定名称为urls。

    2)给N个线程平均分配任务(urls.Count/N,如果无法除尽设法给某个线程多一点的任务)。

    3)然后这N个线程通过for循环启动,每次创建一个线程;分别处理这个List中特定范围内的Url请求。

    4)使用我上面的方法,设置信号AutoEventReset,报告主程序各个子进程都完成任务,输出结果。


    下载MSDN桌面工具(Vista,Win7)
    我的博客园
    慈善点击,点击此处

    嗯嗯。。。

    分配置可以,我想请问版主。像这种大任务http请求;最佳使用应该选择那个{Thread、ThreadPool、Task}

    听说task是在thread\threadpool这两个类上优法得来的。但我不知道他的注体使用方法;

    2012年9月18日 8:14
  • 都是可以的。

    Task可以实现多线程,同时还可以实现异步操作。

    简单做法:

    Task t = new Task(()=>
    {
       //你的东西……
    });
    
    t.Start();

    注意:后台线程!


    下载MSDN桌面工具(Vista,Win7)
    我的博客园
    慈善点击,点击此处

    • 已标记为答案 JJAVEN 2012年9月18日 9:49
    2012年9月18日 8:23
    版主
  • 都是可以的。

    Task可以实现多线程,同时还可以实现异步操作。

    简单做法:

    Task t = new Task(()=>
    {
       //你的东西……
    });
    
    t.Start();

    注意:后台线程!


    下载MSDN桌面工具(Vista,Win7)
    我的博客园
    慈善点击,点击此处

    是不是这样设置线程数量,

    for (int i = 0; i < 10000; i++)

    {

    Task t=new Task(OK)

    t.Start();

    }

    Static void OK()

    {

    cw("输出")

    }

    麻烦版主了,再次感谢!


    • 已标记为答案 JJAVEN 2012年9月18日 9:49
    • 取消答案标记 JJAVEN 2012年9月18日 9:50
    2012年9月18日 9:01
  • 你这是设置每一个线程执行1000遍任务。假设总共有3000个任务,需要3个线程,每一个线程执行1000个任务,那么:

    //假设存在着3000个url的List,那么: for (int i = 0; i < 3; i++) { int temp = i; Task t=new Task ( ()=> { for(int j=temp*1000;j<temp*1000+1000;++j) { //处理你自己的事情…… } } ) t.Start(); }

    注意加上信号机制!


    下载MSDN桌面工具(Vista,Win7)
    我的博客园
    慈善点击,点击此处

    • 已标记为答案 JJAVEN 2012年9月18日 9:49
    2012年9月18日 9:09
    版主
  • 感谢版本对我的无私奉献,本人还有一个疑问就是,这种线程数量是不是跟thraed线程数量是一样。有一个最大数的。

    2012年9月18日 9:49
  • 感谢版本对我的无私奉献,本人还有一个疑问就是,这种线程数量是不是跟thraed线程数量是一样。有一个最大数的。

    最大数?我知道线程池有,线程应该没有限制吧?

    下载MSDN桌面工具(Vista,Win7)
    我的博客园
    慈善点击,点击此处


    2012年9月19日 1:22
    版主
  • 感谢版主老师!

    我今天的新提了一个问题,如果你有空的话,帮我看看!!

    http://social.msdn.microsoft.com/Forums/zh-CN/visualcshartzhchs/thread/756312c1-516e-418d-a1ab-6d31806209ee

    2012年9月19日 9:44