我用多线程写的代码,为什么和单线程速度差不多呢? download()怎么写的,如果有lock之类的锁定或者control.invoke等等的同步,那么就会阻塞住。 解决方案 » 免费领取超大流量手机卡,每月29元包185G流量+100分钟通话, 中国电信官方发货 看着也没啥呀,除非是写文件阻塞了?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++; } 调试发现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++; } 顺便问个问题,我用for语句里面的i作为参数给download,结果发现所有的线程最后WaitAll运行的时候,执行的i都是一个数---> i的终值+1。这是为啥呢?难道task传递参数的时候,要等到wait的时候才真正传递数值吗? 其它的不做评论。但是你使用lamda表达式的时候,就应该了解它的一些负面影响。其中之一:就是在for循环中,不在能lamda表达式中使用一些变量。你可以使用IL反汇编生成的代码出来看一下,就懂了。 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); 改成Parallel.For了Task task=Task.Factory.StartNew(() => Parallel.For(start, end+1, (i) => download(i)) ).ContinueWith((a) => { over(); });下载1000个,看线程能加到600左右 很强大的木马,应该怎么防 webservice 客户端的输入参数的类型验证 asp:DropDownList如何载入一数据表(sql2005)一字段所有值?C#代码如何写? (c#).net中求上传较大文件解决方案 请高手提供个思路 学习c#与遇到的关于this的问题 如何获得datagrid的超连接列的内容? 一个数组最大可以多大 如何去除字符串中除中文外的其他字符,最终只留下中文。 请问关于~符号的解释。 P2P UDP实现的打洞程序就可以实现国内外通信么???? 大婶们帮忙看看下面的小程序哪里出错了?几行代码!找不到错误原因!
看着也没啥呀,除非是写文件阻塞了?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++;
}
private void delay(int ms)
{
id_idx++;
Thread.Sleep(3000);
Thread ts = new Thread(new ThreadStart(info));
ts.IsBackground = true;
ts.Start();
id_idx1++;
}
但是你使用lamda表达式的时候,就应该了解它的一些负面影响。
其中之一:就是在for循环中,不在能lamda表达式中使用一些变量。
你可以使用IL反汇编生成的代码出来看一下,就懂了。
注意:TPL比Thread更具智能性,当它判断任务集并没有从并行运行中受益,就会选择按顺序运行。但并非所有的项目都适合使用并行开发,创建过多并行任务可能会损害程序的性能,降低运行效率。
莫非是这个原因?我把代码改成这样,速度能快一倍,但也没像想象的那样并发一二十个同时进行
Action[] actions = new Action[end - start + 1];
for (int i = start; i <= end; i++)
{
actions[i - start] = () => download();
}
Parallel.Invoke(actions);
Parallel.For(start, end+1, (i) => download(i))
).ContinueWith((a) => { over(); });下载1000个,看线程能加到600左右