c#线程中的循环
我正在用c#开发一个web应用程序。此应用程序使用来自其他应用程序的API,它返回我要转换为datatable的对象数组。我的应用程序的第一个版本使用for循环将数组中的所有对象逐个添加到数据表中。此版本可以正确执行作业,但需要一些时间来处理 所以我决定继续使用多线程,减少处理时间,因为我要部署我的应用程序的服务器有几个核心。然而,我希望以友好的方式创建线程,以便在将来的项目中实现代码的可伸缩性和可重用性 当我执行应用程序时,第一次它运行得很酷,第二次它被循环。我遇到的错误似乎是线程内部的无限循环,但是我不知道它在哪里 任何人都可以。下面是我的代码: Hilos2.aspxc#线程中的循环,c#,multithreading,infinite-loop,C#,Multithreading,Infinite Loop,我正在用c#开发一个web应用程序。此应用程序使用来自其他应用程序的API,它返回我要转换为datatable的对象数组。我的应用程序的第一个版本使用for循环将数组中的所有对象逐个添加到数据表中。此版本可以正确执行作业,但需要一些时间来处理 所以我决定继续使用多线程,减少处理时间,因为我要部署我的应用程序的服务器有几个核心。然而,我希望以友好的方式创建线程,以便在将来的项目中实现代码的可伸缩性和可重用性 当我执行应用程序时,第一次它运行得很酷,第二次它被循环。我遇到的错误似乎是线程内部的无限循
<%@ Page Language="C#" AutoEventWireup="true" CodeFile="Hilos2.aspx.cs" Inherits="Hilos2" %>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head runat="server">
<title></title>
</head>
<body>
<form id="form1" runat="server">
<div>
<asp:GridView id="gvrandom" runat="server" AutoGenerateColumns="true"> </asp:GridView>
</div>
</form>
</body>
</html>
Hilos2.aspx.cs
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Threading;
using System.Data;
public partial class Hilos2 : System.Web.UI.Page
{
clsValues[] vals = new clsValues[1038];
DataSet ds = new DataSet();
protected void Page_Load(object sender, EventArgs e)
{
if (!Page.IsPostBack)
{
ds.Tables.Add("Out");
ds.Tables["Out"].Columns.AddRange(new[] { new DataColumn("Value1", typeof(string)), new DataColumn("Value2", typeof(string)) });
/*this section is just to represent the array i get from the api
the size of the array are similar*/
Random rand = new Random();
for (int i = 0; i < 1038; i++)
{
vals[i] = new clsValues();
vals[i].Value1 = Convert.ToChar(rand.Next(1, 256)).ToString() + Convert.ToChar(rand.Next(1, 256)).ToString() + Convert.ToChar(rand.Next(1, 256)).ToString() +
Convert.ToChar(rand.Next(1, 256)).ToString() + Convert.ToChar(rand.Next(1, 256)).ToString();
vals[i].Value2 = Convert.ToChar(rand.Next(1, 256)).ToString() + Convert.ToChar(rand.Next(1, 256)).ToString() + Convert.ToChar(rand.Next(1, 256)).ToString() +
Convert.ToChar(rand.Next(1, 256)).ToString() + Convert.ToChar(rand.Next(1, 256)).ToString();
}
int elementsXthread = (int)Math.Truncate((double)(vals.Length / Environment.ProcessorCount));
int elementsLastThread;
int elementsToProcess;
int posStartProcess = 0;
List<Thread> thr = new List<Thread>();
if (elementsXthread * Environment.ProcessorCount != vals.Length)
{
elementsLastThread = elementsXthread + vals.Length - (elementsXthread * Environment.ProcessorCount);
}
else
{
elementsLastThread = elementsXthread;
}
elementsToProcess = elementsXthread;
for (int i = 1; i < Environment.ProcessorCount + 1; i++)
{
if (i == Environment.ProcessorCount)
{
elementsToProcess = elementsLastThread;
}
if (elementsToProcess + posStartProcess <= vals.Length)
{
int param1, param2;
param1 = elementsToProcess;
param2 = posStartProcess;
Thread tdr = new Thread(() => rnd(param1, param2));
tdr.Start();
thr.Add(tdr);
posStartProcess += elementsToProcess;
}
}
foreach (Thread tdr in thr)
{
tdr.Join();
}
gvrandom.DataSource = ds.Tables["Out"];
gvrandom.DataBind();
}
}
private void rnd(int iter, int posinicio)
{
for (int iterador = 0; iterador < iter; iterador++)
{
System.Data.DataRow dr = ds.Tables["Out"].NewRow();
dr["Value1"] = vals[iterador + posinicio].Value1;
dr["Value2"] = vals[iterador + posinicio].Value2;
ds.Tables["Out"].Rows.Add(dr);
}
}
}
public class clsValues
{
string value1, value2;
public string Value1
{
get
{
return value1;
}
set
{
value1 = value;
}
}
public string Value2
{
get
{
return value2;
}
set
{
value2 = value;
}
}
}
使用系统;
使用System.Collections.Generic;
使用System.Linq;
使用System.Web;
使用System.Web.UI;
使用System.Web.UI.WebControl;
使用系统线程;
使用系统数据;
公共部分类Hilos2:System.Web.UI.Page
{
CLS值[]VAL=新的CLS值[1038];
数据集ds=新数据集();
受保护的无效页面加载(对象发送方、事件参数e)
{
如果(!Page.IsPostBack)
{
ds.表格。添加(“外”);
ds.Tables[“Out”].Columns.AddRange(新[]{new DataColumn(“Value1”,typeof(string)),new DataColumn(“Value2”,typeof(string))});
/*本节仅表示我从api获得的数组
数组的大小相似*/
Random rand=新的Random();
对于(int i=0;i<1038;i++)
{
VAL[i]=新的CLS值();
vals[i].Value1=Convert.ToChar(rand.Next(1256)).ToString()+Convert.ToChar(rand.Next(1256)).ToString()+Convert.ToChar(rand.Next(1256)).ToString()+
Convert.ToChar(rand.Next(1256)).ToString()+Convert.ToChar(rand.Next(1256)).ToString();
vals[i].Value2=Convert.ToChar(rand.Next(1256)).ToString()+Convert.ToChar(rand.Next(1256)).ToString()+Convert.ToChar(rand.Next(1256)).ToString()+
Convert.ToChar(rand.Next(1256)).ToString()+Convert.ToChar(rand.Next(1256)).ToString();
}
int-elementsXthread=(int)Math.Truncate((double)(vals.Length/Environment.ProcessorCount));
int-elementsLastThread;
int元素停止进程;
int posStartProcess=0;
List thr=新列表();
if(elementsxread*Environment.ProcessorCount!=vals.Length)
{
elementsLastThread=elementsXthread+vals.Length-(elementsXthread*Environment.ProcessorCount);
}
其他的
{
elementsLastThread=elementsXthread;
}
elementsToProcess=elementsxread;
对于(int i=1;i
您没有阻止线程争用。线程在与ds交互时都会发生冲突
申报一把锁
private object myLock = new object();
B.使用锁定随机方法:
private void rnd(int iter, int posinicio)
{
for (int iterador = 0; iterador < iter; iterador++)
{
System.Data.DataRow dr = ds.Tables["Out"].NewRow();
dr["Value1"] = vals[iterador + posinicio].Value1;
dr["Value2"] = vals[iterador + posinicio].Value2;
lock (myLock)
{
ds.Tables["Out"].Rows.Add(dr);
}
}
}
private void rnd(内部iter,内部posinicio)
{
对于(int-iterador=0;iterador
您的第一个问题是,您正在从多个线程修改数据表。报告说:
此类型对于多线程读取操作是安全的。必须同步任何写入操作
所以有多个线程都在盲目地更新表。如果其中两个或多个用户同时尝试执行更新,则结果是不可预测的。它们可能不是你想要的
如果继续进行同步,我会非常惊讶地看到多线程版本比单线程版本运行得更快。如果您的线程所做的只是向表中添加内容,那么它们将花费大部分时间等待锁。使用多个线程不会给您带来任何好处,因为这些线程并行执行的工作不多
简言之,在这种情况下使用多线程并不是一种胜利。省去麻烦,用一个线程就可以了。这是一种实现多线程的糟糕方法,尤其是在ASP.NET应用程序中,而且根本没有线程安全性