多线程c#中出现意外行为

时间:2015-03-18 19:00:50

标签: c# asp.net multithreading

我是多线程的新手并且开始做一些研究和实验,最近在C#中编写了一个多线程Web表单,它动态地根据服务器上安装的核心数创建线程。每个线程共享和数组,并有两个参数。该数组先前已填充数据,参数包含要在数组中处理的起始位置以及要处理的元素数。

我的代码是:

Hilos.aspx

<%@ Page Language="C#" AutoEventWireup="true" CodeFile="Hilos.aspx.cs" Inherits="Hilos" %>

<!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:Label ID="lbl" runat="server"></asp:Label>
    </div>
    </form>
</body>
</html>

Hilos.aspx.cs

using System;
using System.Collections.Generic;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Threading;

public partial class Hilos : System.Web.UI.Page
{
  static List<int> var = new List<int>();
  static List<object> hilo = new List<object>();

  string[] abc = { "abc", "def", "ghi", "jkl", "mnñ", "opq", "rst", "uvw", "xyz" };
  List<string> lstStr = new List<string>();

  protected void Page_Load(object sender, EventArgs e)
  {
    if (!Page.IsPostBack)
    {            
        int elementosPorHilo = (int)Math.Truncate((double)(abc.Length / Environment.ProcessorCount));
        int elementosUltimoHilo;
        int elementosProcesar;
        int posInicioProcesar = 0;
        List<Thread> thr = new List<Thread>();

        if (elementosPorHilo * Environment.ProcessorCount != abc.Length)
        {
            elementosUltimoHilo = elementosPorHilo + abc.Length - (elementosPorHilo * Environment.ProcessorCount);
        }
        else
        {
            elementosUltimoHilo = elementosPorHilo;
        }

        elementosProcesar = elementosPorHilo;

        //This for creates the threads and should create one core per avaiable thread on the processor(s)
        for (int i = 1; i < Environment.ProcessorCount + 1; i++)
        {
            if (i == Environment.ProcessorCount)
            {
                elementosProcesar = elementosUltimoHilo;
            }
            Thread tdr = new Thread(() => rnd(elementosProcesar, posInicioProcesar));
            tdr.Start();
            thr.Add(tdr);
            posInicioProcesar += elementosProcesar;
        }
        foreach (Thread tdr in thr)
        {
            tdr.Join();
        }
        lbl.Text = string.Concat(lstStr.ToArray());
      }
  }
  /// <summary>
  /// Code executed by the Thread
  /// </summary>
  /// <param name="iter">How many times it will iterate</param>
  /// <param name="posinicio">The start position inside the Array</param>
  private void rnd(int iter, int posinicio)
  {

    string str = "";

    for (int iterador = 0; iterador < iter; iterador ++)
    {
        str += abc[iterador + posinicio];
    }

    lstStr.Add(str);    
   }
  }

我在四核Core i3 pc(4线程,因为HyperThreading)Windows 7 x86上运行。我遇到的问题是代码创建了5个线程,最后一个线程显然是使用超出数组限制的参数创建的。

使用iter = 3和posinicio = 6创建最后一个正确的线程,之后使用iter = 3和posinicio = 9创建另一个线程,并在执行时,发送和错误指示索引异常。

我知道它可以在创建de线程的for中控制,但我想理解为什么会发生这种情况。

谢谢你,对不起,感谢对不起。

0 个答案:

没有答案