asp.net多线程编程

gs8716 2010-06-21 10:27:26
我用asp.net web 和window form 都测试过,winform中多了一句System.Windows.Forms.Control.CheckForIllegalCrossThreadCalls = false;线程数目与指定的相同,但是累和结果不对。在asp.net web当中线程数目不与指定数目相同,有时多有时少但都没有达到指定的数目,每次重新计算结果都不一样。

我本人不懂多线程编程的,这些代码是在网上找的
现在问题是:
1、修改代码让其显示结果正确(可以单独做一个循环测试结果是多少,我测试从1累加到1亿是5 000 000 050 000 000)
2、我现在要用多线程批量静态生成,文章数目在3万以上,20万以内,求相关代码,注意效率问题(关于线程编程就可以,分数是另给的100分)

前台代码:

<div><p>累加开始于:<asp:TextBox ID="txtMinValue" runat="server"></asp:TextBox></p>
<p>累加结束于:<asp:TextBox ID="txtMaxValue" runat="server"></asp:TextBox></p>
<p>使用线程数:<asp:TextBox ID="txtThreadNumber" runat="server"></asp:TextBox><asp:Button ID="Button1" runat="server" Text="开始计算" OnClick="Button1_Click" /></p>

<p>累加结果:<asp:TextBox ID="txtOutput" runat="server"></asp:TextBox></p>
<p>信息:</p>
<asp:ListBox ID="lstMessage" runat="server" Height="244px" Width="353px"></asp:ListBox>
</div>

后台代码

protected void Button1_Click(object sender, EventArgs e)
{
txtOutput.Text = "0";
lstMessage.Items.Clear();
int threadNumber = Convert.ToInt32(this.txtThreadNumber.Text);
for (int i = 1; i <= threadNumber; i++)
{
try
{
Thread thread = new Thread(new ThreadStart(Add));
thread.Name = i.ToString();
//thread.Priority = ThreadPriority.Normal;
thread.Start();
}
catch (Exception ex)
{
throw new Exception(ex.Message);
}
finally
{

}
}
}
private void Add()
{
DateTime beginTime = DateTime.Now;
long minValue = long.Parse(txtMinValue.Text);
long maxValue = long.Parse(txtMaxValue.Text);
int threadNumber = Convert.ToInt32(txtThreadNumber.Text);
int thradOrder = Convert.ToInt32(Thread.CurrentThread.Name);
long step = (maxValue - minValue + 1) / threadNumber;
long beginValue = minValue + step*(thradOrder-1);
long result = 0;
long endValue=beginValue+step;
for (long i = beginValue; i < endValue; i++)
{
result += i;
}
lock (this)//线程同步锁
{
long sum = long.Parse(txtOutput.Text);
sum += result;
txtOutput.Text = sum.ToString();
}
DateTime endTime = DateTime.Now;
TimeSpan timeSpan = endTime - beginTime;
string message = "线程" + Thread.CurrentThread.Name + ":" + beginValue.ToString() + "到" + endValue.ToString()
+ ",耗时:" + timeSpan.TotalMilliseconds.ToString() + "毫秒";
this.lstMessage.Items.Add(message);
Response.Write(message + "<br/>");
Thread.CurrentThread.Abort();
}
...全文
165 11 打赏 收藏 转发到动态 举报
写回复
用AI写文章
11 条回复
切换为时间正序
请发表友善的回复…
发表回复
gs8716 2010-06-21
  • 打赏
  • 举报
回复
[Quote=引用 9 楼 ihandler 的回复:]
线程1:1到334,耗时:0毫秒
线程2:334到667,耗时:0毫秒
线程3:667到1000,耗时:0毫秒



累加开始于:1

累加结束于:1000

使用线程数:3

累加结果:499500

信息:

线程1:1到334,耗时:0毫秒 线程2:334到667,耗时:0毫秒 线程3:667到1000,耗时:0毫秒
[/Quote]

你用我的数据试下
myhope88 2010-06-21
  • 打赏
  • 举报
回复
路过,帮顶下
IHandler 2010-06-21
  • 打赏
  • 举报
回复
线程1:1到334,耗时:0毫秒
线程2:334到667,耗时:0毫秒
线程3:667到1000,耗时:0毫秒



累加开始于:1

累加结束于:1000

使用线程数:3

累加结果:499500

信息:

线程1:1到334,耗时:0毫秒 线程2:334到667,耗时:0毫秒 线程3:667到1000,耗时:0毫秒
IHandler 2010-06-21
  • 打赏
  • 举报
回复
线程1:1到51,耗时:0毫秒
线程2:51到101,耗时:0毫秒



累加开始于:1

累加结束于:100

使用线程数:2

累加结果:5050
信息:

线程1:1到51,耗时:0毫秒 线程2:51到101,耗时:0毫秒
gs8716 2010-06-21
  • 打赏
  • 举报
回复
[Quote=引用 6 楼 ihandler 的回复:]
我试了一下,计算结果是一样的
[/Quote]

难道是我的VS有问题?


线程2:16666667到33333333,耗时:156.25毫秒
线程1:1到16666667,耗时:171.875毫秒


累加开始于:1

累加结束于:100000000

使用线程数:6

累加结果:555555527777778

信息:

线程2:16666667到33333333,耗时:156.25毫秒
线程1:1到16666667,耗时:171.875毫秒

IHandler 2010-06-21
  • 打赏
  • 举报
回复
我试了一下,计算结果是一样的
gs8716 2010-06-21
  • 打赏
  • 举报
回复
[Quote=引用 3 楼 luqc1985 的回复:]
C# code

在 asp.net用一个线程来生成静态页面并不是什么难的事,但要实时调用正在生成数据的相关信息及进度就不是那么容易的事了,把线程定义成static,可以全局调用,并且只要不关闭iis进程,生成页面操作一样还在进行着,在客户端那怕是重启了电脑再来打开生成静态页面的页面,进度还在进行.

public static Thread myThread ;

cMyThread……
[/Quote]

看你的应该主要是针对显示进度条的,我现在不考虑这个,只要用多线程来批量静态生成从而提高效率
灵雨飘零 2010-06-21
  • 打赏
  • 举报
回复
帮顶。。。。。
别样苍茫 2010-06-21
  • 打赏
  • 举报
回复

在 asp.net用一个线程来生成静态页面并不是什么难的事,但要实时调用正在生成数据的相关信息及进度就不是那么容易的事了,把线程定义成static,可以全局调用,并且只要不关闭iis进程,生成页面操作一样还在进行着,在客户端那怕是重启了电脑再来打开生成静态页面的页面,进度还在进行.

public static Thread myThread ;

cMyThread.myThread = new Thread(StartCreate.Intance.CreateHtmls);
cMyThread.myThread.Start();


StartCreate里保存了当前生成页面的相关信息,如StartCreate.title,StartCreate.singer,StartCreate.musicname

StartCreate 一样为静态的

这样让显示进度的页面实现接口

public partial class StartCreatPages : Page, ICallbackEventHandler

ClientScriptManager cs = Page.ClientScript;
if (Page.Request.Browser.SupportsXmlHttp)
{
string callbackScript = cs.GetCallbackEventReference(
this, //代表处理客户端回调的控件为当前页
"SendValue()", //是页面上的一个javascript函数,该函数返回的是用户在TextBox中输入的用户名,用户名将提交到服务器进行判断,GetClientUserName()函数的具体内容将在下面补上
"OnCallbackCompleted", //表示接收服务器端事件处理结果的javascript函数为 OnCallbackCompleted 函数
null, //这个实例不需要用到这个参数,所以给它一个空值。这个参数的具体作用见上面MSDN的解释
"OnServerError", //"OnServerError",这个参数指定了当服务器端处理出错时,由客户端的javascript函数OnServerError()来接收错误信息并处理。在这个实例中,当用户在TextBox里输入 "生铁猪" 的时候服务器端会抛出错误并调用客户端函数OnServerError()处理错误并显示
true //true 表示同步执行这次回调
);

//GetCallbackEventReference函数将根据参数返回一个string类型的发送回调请求的脚本,我们把这个脚本保存在callbackScript变量中
string callbackScriptMethod = "function CallbackScriptMethod() { " + callbackScript + " ;}";//这条语句将拼接一个名为CallbackScriptMethod的javascript脚本,然后把回调请求脚本放在这个函数体内。这样做以后就可以在javascript里通过CallbackScriptMethod() 函数引发回调

//以下这条语句把引发回调的函数CallbackScriptMethod()发送到客户端
cs.RegisterClientScriptBlock(this.GetType(), "CallbackScriptMethod", callbackScriptMethod, true);
}
else
{
cs.RegisterStartupScript(this.GetType(), "SupportsXmlHttp", "alert('你的浏览器不支持XmlHttp,不能使用回调功能!')", true);
}



public string GetCallbackResult()
{
return CallbackResult;
}


public void RaiseCallbackEvent(string eventArgument)
{
CallbackResult = //这里调用StartCreate里的相关内容,StartCreate.singer,StartCreate.musicname

//当然要返回当前数与最大数,这样才能在页面上实现进度

}


进度页面代码

<script type="text/javascript" language="javascript">

var percenttimer = 0;
var SPLITTER_RECORD = "{\r\r*\r\r}";
var aCurrentmusicinfo = null;
function WriteProcess(full, part)
{
var w = parseInt(part*500/full);
var strHtml = "<center style='font-size:12px;font-family:Arial;'><div style='width:500px; height:10px; border:1px #F7D4D4 solid;font-size:5px;' align='left'>";
strHtml +="<div style='width:"+ w +"px;height:10px;background:#4DADF4;'></div></div>"+parseInt(part*100/full) +"%</center>";
progress.innerHTML = strHtml;
}

function OnCallbackCompleted(CallbackResult,context)
{

aCurrentmusicinfo = CallbackResult.split(SPLITTER_RECORD);

WriteProcess(aCurrentmusicinfo[2],aCurrentmusicinfo[3]);

var strCurrentInfo = "正在生成:"+aCurrentmusicinfo[5]+"<br>生成情况:"+aCurrentmusicinfo[6]+"<br>歌曲名称:"+aCurrentmusicinfo[0]+"<br>歌手:"+aCurrentmusicinfo[1]+"<br>共有"+aCurrentmusicinfo[2]+"条记录,已经完成"+aCurrentmusicinfo[3]+"条<br>当前线程: "+aCurrentmusicinfo[4];

currentinfo.innerHTML = strCurrentInfo;
}

function OnServerError(error)
{
alert("错误信息 " + error);
}
function SendValue()
{
return 50;
}

percenttimer = setInterval("CallbackScriptMethod()",1000);


</script>
</head>
<body>
<form id="form1" runat="server">
<br />
<div style="text-align:center">
<asp:Button ID="btStart" runat="server" Text="开 始" Width="123px" OnClick="btStart_Click" />
<br /><br />
<asp:Button ID="btAbort" runat="server" OnClick="btAbort_Click" Text="中 断" />
       
<asp:Button ID="btClear" runat="server" Text="终 止"
onclick="btClear_Click" />
</div>
<br /><br />
<div id="progress">
</div>

<div id="currentinfo">
</div>
</form>

symbol_bc 2010-06-21
  • 打赏
  • 举报
回复
我没做过多线程,但我总觉得用for循环生成线程好像有点...没见过。
线程应该是很稀缺的资源,一般两三个就了不得了,不懂帮顶。
凤凰涅檠 2010-06-21
  • 打赏
  • 举报
回复
SF,关注

62,025

社区成员

发帖
与我相关
我的任务
社区描述
.NET技术交流专区
javascript云原生 企业社区
社区管理员
  • ASP.NET
  • .Net开发者社区
  • R小R
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告

.NET 社区是一个围绕开源 .NET 的开放、热情、创新、包容的技术社区。社区致力于为广大 .NET 爱好者提供一个良好的知识共享、协同互助的 .NET 技术交流环境。我们尊重不同意见,支持健康理性的辩论和互动,反对歧视和攻击。

希望和大家一起共同营造一个活跃、友好的社区氛围。

试试用AI创作助手写篇文章吧