download()怎么写的,如果有lock之类的锁定或者control.invoke等等的同步,那么就会阻塞住。

解决方案 »

  1.   


    看着也没啥呀,除非是写文件阻塞了?private void downloadsgf(string token, string dirpath, int max)
            {            int i = id_idx;
                if (id_idx > max)
                {
                    importCts.Cancel();
                    id_idx1++;
                    return;
                }
                id_idx++;            Thread ts = new Thread(new ThreadStart(info));
                ts.IsBackground = true;
                ts.Start();            //Console.Beep(1000, 100);
                //Debug.WriteLine(i.ToString());
                string postString = @"pid=" + i.ToString() +
                                    @"&csrfmiddlewaretoken=" + token;            string downurl1 = @"******************";
                string responsetext = string.Empty;
                HttpStatusCode statuscode = HttpHelper.GetResponse(ref responsetext, downurl1, "POST", postString);
                if (!responsetext.Contains(@"/"))
                {
                    resultmsg += @"返回文件链接错误" + i + " responsetext:" + responsetext + Environment.NewLine;
                    id_idx1++;
                    return;
                }
                string[] aryfilename = responsetext.Split('\"');
                string filename = aryfilename[aryfilename.Length - 2];
                //Clipboard.SetDataObject(responsetext, true);
                if (filename == "result")
                {
                    resultmsg += @"文件名解析错误:" + i + " " + filename + Environment.NewLine;
                    return;
                }
                string downurl2 = @"**************" + Uri.EscapeUriString(filename);            statuscode = HttpHelper.GetResponse(ref responsetext, downurl2, "Get", string.Empty);            if (statuscode == HttpStatusCode.OK)
                {
                    int idx = filename.LastIndexOf('/');
                    filename = filename.Substring(idx + 1, filename.Length - idx - 1);
                    filename = filterFilename(filename);
                    FileStream fs = new FileStream(dirpath + filename, FileMode.Create);
                    StreamWriter sw = new StreamWriter(fs);
                    sw.Write(responsetext);  //开始写入
                    sw.Flush();              //清空缓冲区
                    sw.Close();              //关闭流
                    fs.Close();
                    count_success++;
                }
                else
                {
                    resultmsg += i + Environment.NewLine;
                }
                id_idx1++;
            }
      

  2.   

    调试发现task好像启动线程很慢呀,50个线程启动要等半天我把download()换成下面的代码,居然要24秒。不加延时也要2~3秒。
    private void delay(int ms)
            {
                id_idx++;
                Thread.Sleep(3000);
                Thread ts = new Thread(new ThreadStart(info));
                ts.IsBackground = true;
                ts.Start();
                id_idx1++;
            }
      

  3.   

    顺便问个问题,我用for语句里面的i作为参数给download,结果发现所有的线程最后WaitAll运行的时候,执行的i都是一个数---> i的终值+1。这是为啥呢?难道task传递参数的时候,要等到wait的时候才真正传递数值吗?
      

  4.   

    其它的不做评论。
    但是你使用lamda表达式的时候,就应该了解它的一些负面影响。
    其中之一:就是在for循环中,不在能lamda表达式中使用一些变量。
    你可以使用IL反汇编生成的代码出来看一下,就懂了。
      

  5.   

    System.Threading.Tasks中的类被统称为任务并行库(Task Parallel Library,TPL),TPL使用CLR线程池把工作分配到CPU,并能自动处理工作分区、线程调度、取消支持、状态管理以及其他低级别的细节操作,极大地简化了多线程的开发。
    注意:TPL比Thread更具智能性,当它判断任务集并没有从并行运行中受益,就会选择按顺序运行。但并非所有的项目都适合使用并行开发,创建过多并行任务可能会损害程序的性能,降低运行效率。
    莫非是这个原因?我把代码改成这样,速度能快一倍,但也没像想象的那样并发一二十个同时进行
    Action[] actions = new Action[end - start + 1];
    for (int i = start; i <= end; i++)
    {
        actions[i - start] = () => download();
    }
    Parallel.Invoke(actions);
      

  6.   

    改成Parallel.For了Task task=Task.Factory.StartNew(() =>
                Parallel.For(start, end+1, (i) => download(i))
                ).ContinueWith((a) => { over(); });下载1000个,看线程能加到600左右