I'm new to Multithreading and began to do some research and experiments and recently wrote a Multithreading web form in C#, that dynamically, creates threads depending the number of cores installed on the server. Each thread shares and array and has two parameters. The array is previously filled with data and the parameters contains the beginning position to process in the array and the number of elements to process.
My code is this :
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);
}
}
I'm running this on a four cores Core i3 pc (4 threads because HyperThreading) Windows 7 x86. The problem I'm having is that the code is creating 5 threads and the last thread obviously is created with parameters outside the limits of the array.
The last one correct thread is created with iter = 3 and posinicio = 6 and after that another thread is created with iter = 3 and posinicio = 9 and when it executes, sends and error indicating out of index exception.
I know it can be controlled in the for that creates de threads but i would like to understand why it is this happening.
Thanks you and sorry for the long post.