Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/multithreading/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
c#线程中的循环_C#_Multithreading_Infinite Loop - Fatal编程技术网

c#线程中的循环

c#线程中的循环,c#,multithreading,infinite-loop,C#,Multithreading,Infinite Loop,我正在用c#开发一个web应用程序。此应用程序使用来自其他应用程序的API,它返回我要转换为datatable的对象数组。我的应用程序的第一个版本使用for循环将数组中的所有对象逐个添加到数据表中。此版本可以正确执行作业,但需要一些时间来处理 所以我决定继续使用多线程,减少处理时间,因为我要部署我的应用程序的服务器有几个核心。然而,我希望以友好的方式创建线程,以便在将来的项目中实现代码的可伸缩性和可重用性 当我执行应用程序时,第一次它运行得很酷,第二次它被循环。我遇到的错误似乎是线程内部的无限循

我正在用c#开发一个web应用程序。此应用程序使用来自其他应用程序的API,它返回我要转换为datatable的对象数组。我的应用程序的第一个版本使用for循环将数组中的所有对象逐个添加到数据表中。此版本可以正确执行作业,但需要一些时间来处理

所以我决定继续使用多线程,减少处理时间,因为我要部署我的应用程序的服务器有几个核心。然而,我希望以友好的方式创建线程,以便在将来的项目中实现代码的可伸缩性和可重用性

当我执行应用程序时,第一次它运行得很酷,第二次它被循环。我遇到的错误似乎是线程内部的无限循环,但是我不知道它在哪里

任何人都可以。下面是我的代码:

Hilos2.aspx

<%@ 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应用程序中,而且根本没有线程安全性