我是线程新手,我目前使用Tasks来执行多线程。正如您在代码中看到的那样,一组任务从Excel执行一系列提取,Task.WaitAll()
正在按预期工作。
但是对于第二组任务,Task.WaitAll()
没有按预期工作。控件将直接转到任务池外的下一个方法,而不是等待任务完成。
我正在使用第一组任务从Excel中提取,并使用下一组任务将值存储在对象中。
提前致谢。
// MainClass.cs
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Threading;
namespace ConsoleApplication2
{
/// <summary>
/// class to call the methods to extract values and assign values using multithreading
/// </summary>
public class MainClass : ExtractValues
{
public static int size;
static void Main(string[] args)
{
ExtractValues objectOfExtractValues = new ExtractValues();
Values objectOfValues = new Values();
size = objectOfExtractValues.initialize();
List<int> Range = new List<int>();
Range = objectOfExtractValues.cellRangeFinder();
//creating a new task to call methods to extract details from the excel to run parallelly
Task[] task = new Task[6];
{
task[0] = Task.Factory.StartNew(() => objectOfExtractValues.thread1(Range[0]));
task[1] = Task.Factory.StartNew(() => objectOfExtractValues.thread2(Range[0], Range[1]));
task[2] = Task.Factory.StartNew(() => objectOfExtractValues.thread3(Range[2], Range[3]));
task[3] = Task.Factory.StartNew(() => objectOfExtractValues.thread4(Range[4], Range[5]));
task[4] = Task.Factory.StartNew(() => objectOfExtractValues.thread5(Range[6], Range[7]));
task[5] = Task.Factory.StartNew(() => objectOfExtractValues.thread6(Range[8], Range[9]));
}
Task.WaitAll(task);
objectOfValues.init();
Task tasknew1 = Task.Factory.StartNew(() => objectOfValues.assignValues1());
Task tasknew2 = Task.Factory.StartNew(() => objectOfValues.assignValues2());
Task tasknew3 = Task.Factory.StartNew(() => objectOfValues.assignValues3());
Task tasknew4 = Task.Factory.StartNew(() => objectOfValues.assignValues4());
Task tasknew5 = Task.Factory.StartNew(() => objectOfValues.assignValues5());
Task tasknew6 = Task.Factory.StartNew(() => objectOfValues.assignValues6());
Task tasknew7 = Task.Factory.StartNew(() => objectOfValues.assignValues7());
Task.WaitAll(tasknew1, tasknew2, tasknew3, tasknew4, tasknew5, tasknew6, tasknew7);
//Task.WhenAll();
//Task.WaitAll();
//calling method to initialize the object array
// creating another task to call methods to assign details stored in the list to objects parallelly
objectOfExtractValues.endProcess();
// wait
Console.ReadLine();
objectOfValues.show();
}
}
}
** ExtractValue.cs **
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Excel = Microsoft.Office.Interop.Excel;
using System.Threading.Tasks;
using System.Runtime.InteropServices;
using System.Threading;
namespace ConsoleApplication2
{
/// <summary>
/// class containing methods to extract values from the excel
/// </summary>
public class ExtractValues
{
public int rowCount;
public int colCount;
//lists to store values from different sections of the excel
public static List<int> rangeList = new List<int>();
public static List<string> tempList = new List<string>();
public static List<string> tempList2 = new List<string>();
public static List<string> tempList3 = new List<string>();
public static List<string> tempList4 = new List<string>();
public static List<string> tempList5 = new List<string>();
public static List<string> tempList6 = new List<string>();
public static List<string> tempList7 = new List<string>();
string path = System.Reflection.Assembly.GetExecutingAssembly().Location;
Excel.Application xlApp;
Excel.Workbook xlWorkbook;
Excel._Worksheet xlWorksheet;
Excel.Range xlRange;
int start, end;
/// <summary>
/// method to initaialize the excel and get the column and row count
/// </summary>
public int initialize()
{
var dir = System.IO.Path.GetDirectoryName(path);
string location = dir + "\\some.xlsx";
xlApp = new Excel.Application();
xlWorkbook = xlApp.Workbooks.Open(location);
xlWorksheet = xlWorkbook.Sheets[1];
xlRange = xlWorksheet.UsedRange;
rowCount = xlWorksheet.UsedRange.Rows.Count;
colCount = xlWorksheet.Columns.CurrentRegion.EntireColumn.Count;
return colCount;
}
/// <summary>
/// method to read from the excel file and print it. method reads the rows until the count passed to it.
/// </summary>
/// <param name="count"></param>
public void thread1(int count)
{
for (int i = 2; i <colCount; i++)
{
for (int j = 1; j < count; j++)
{
if (xlRange.Cells[j, i].Value == null && xlRange.Cells[j + 1, i].Value != null)
{
tempList.Add(" ");
}
if (xlRange.Cells[j, i] != null && xlRange.Cells[j, i].Value != null )
tempList.Add(xlRange.Cells[j, i].Value.ToString());
}
}
// for loop to read the cardpan row
for (int i = 2; i <= colCount; i++)
{
for (int j = 12; j <= 12; j++)
{
if (xlRange.Cells[j, i] != null && xlRange.Cells[j, i].Value != null)
tempList7.Add(xlRange.Cells[j, i].Value.ToString());
}
}
}
/// <summary>
/// method to read from the excel file and print it. method reads the rows from and until the count passed to it.
/// </summary>
public void thread2(int count1, int count2)
{
for (int i = 2; i <= colCount; i++)
{
for (int j = count1; j <=count2; j++)
{
if (xlRange.Cells[j, i] != null && xlRange.Cells[j, i].Value != null)
tempList2.Add(xlRange.Cells[j, i].Value.ToString());
}
}
}
/// <summary>
/// method to read from the excel file and print it. method reads the rows from and until the count passed to it.
/// </summary>
/// <param name="count1"></param>
/// <param name="count2"></param>
public void thread3(int count1, int count2)
{
for (int i = 2; i <= colCount; i++)
{
for (int j = count1; j <= count2; j++)
{
if (xlRange.Cells[j, i] != null && xlRange.Cells[j, i].Value != null)
tempList3.Add(xlRange.Cells[j, i].Value.ToString());
}
}
}
/// <summary>
/// method to read from the excel file and print it. method reads the rows from and until the count passed to it.
/// </summary>
/// <param name="count1"></param>
/// <param name="count2"></param>
public void thread4(int count1, int count2)
{
for (int i = 2; i <= colCount; i++)
{
for (int j = count1; j <= count2; j++)
{
if (xlRange.Cells[j, i].Value == null && xlRange.Cells[j + 1, i].Value == null)
{
tempList4.Add(" ");
break;
}
if (xlRange.Cells[j, i] != null && xlRange.Cells[j, i].Value != null)
tempList4.Add(xlRange.Cells[j, i].Value.ToString());
}
}
}
/// <summary>
/// method to read from the excel file and print it. Method reads the rows from and until the count passed to it.
/// </summary>
/// <param name="count1"></param>
/// <param name="count2"></param>
public void thread5(int count1, int count2)
{
for (int i = 2; i <= colCount; i++)
{
for (int j = count1; j <= count2; j++)
{
if (xlRange.Cells[j, i].Value == null && xlRange.Cells[j + 1, i].Value == null)
{
tempList5.Add(" ");
break;
}
if (xlRange.Cells[j, i] != null && xlRange.Cells[j, i].Value != null)
tempList5.Add(xlRange.Cells[j, i].Value.ToString());
//add useful things here!
}
}
}
/// <summary>
/// method to read from the excel file and print it. method reads the rows from and till the count passed to it.
/// </summary>
/// <param name="count1"></param>
/// <param name="count2"></param>
public void thread6(int count1, int count2)
{
for (int i = 2; i <= colCount; i++)
{
for (int j = count1; j <= count2; j++)
{
if (xlRange.Cells[j, i].Value == null && xlRange.Cells[j + 1, i].Value == null)
{
tempList6.Add(" ");
break;
}
if (xlRange.Cells[j, i] != null && xlRange.Cells[j, i].Value != null)
tempList6.Add(xlRange.Cells[j, i].Value.ToString());
}
}
}
/// <summary>
/// method to end the excel file operations
/// </summary>
public void endProcess()
{
xlWorkbook.Close();
GC.Collect();
GC.WaitForPendingFinalizers();
Marshal.ReleaseComObject(xlRange);
Marshal.ReleaseComObject(xlWorksheet);
//close and release
Marshal.ReleaseComObject(xlWorkbook);
//quit and release
xlApp.Quit();
Marshal.ReleaseComObject(xlApp);
}
/// <summary>
/// method to find the merged cells in the excel and store their starting and ending cell values in a list
/// </summary>
/// <returns></returns>
public List<int> cellRangeFinder()
{
for (int i = 1; i <= rowCount; i++)
{
for (int k = 1; k <=1 ; k++)
{
if (xlRange.Cells[i, k] != null && xlRange.Cells[i+1, k].Value == null)
{
start = i;
int tempCounter = i + 1;
while(xlRange.Cells[tempCounter, k].Value == null && (tempCounter<=rowCount+3))
{
tempCounter++;
}
end = tempCounter-1;
rangeList.Add(start);
rangeList.Add(end);
i = tempCounter-1;
}
}
}
return rangeList;
}
}
}
Values.cs
enter code here
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace ConsoleApplication2
{
/// <summary>
/// Class to store the values in the objects
/// </summary>
public class Values : MainClass
{
// Variables to store the values of each object
public int ID { get; set; }
public string tType { get; set; }
public string cType { get; set; }
public string tName { get; set; }
public string SNumber { get; set; }
public string title { get; set; }
public string objective { get; set; }
public string reference { get; set; }
public string prerequisite { get; set; }
public string procedure { get; set; }
public string cPan { get; set; }
public string amount { get; set; }
public string pHost { get; set; }
public string pCard { get; set; }
public string cSlip { get; set; }
// Declaring the Values' class object array
Values[] list;
/// <summary>
/// method to set the size of the array object
/// </summary>
public void init()
{
list= new Values[size];
}
/// <summary>
/// Method to assign the values of the first temp list into the object array
/// </summary>
/// <param name="size"> size varaible is to check the creating of new objects</param>
public void assignValues1()
{
int m = 0;
list[m] = new Values();
for (int i = 0; i < tempList.Count();)
{
list[m].ID = Convert.ToInt32(tempList[i]);
list[m].tType = tempList[i + 1];
list[m].cType = tempList[i + 2];
list[m].tName = tempList[i + 3];
list[m].SNumber = tempList[i + 4];
list[m].title = tempList[i + 5];
list[m].objective = tempList[i + 6];
list[m].reference = tempList[i + 7];
list[m].prerequisite = tempList[i + 8];
i = i + 9;
m++;
if (m < size)
list[m] = new Values();
else
break;
}
}
/// <summary>
/// Method to assign the values of the sevent temp list into the object array which contains Card Pan
/// </summary>
public void assignValues2()
{
int m = 0;
list[m] = new Values();
for (int i = 0; i < tempList7.Count();)
{
list[m].cPan = tempList7[i];
i = i + 1;
m++;
if (m < size)
list[m] = new Values();
else
break;
}
}
/// <summary>
/// Method to assign the values of the second temp list into the object array which contains the procedure
/// </summary>
/// <param name="size"> size varaible is to check the creating of new objects</param>
public void assignValues3()
{
int m = 0;
list[m] = new Values();
for (int i = 0; i < tempList2.Count();)
{
list[m].procedure = tempList2[i] + tempList2[i+1];
i = i + 2;
m++;
if (m < size)
list[m] = new Values();
else
break;
}
}
/// <summary>
/// Method to assign the values of the amount temp list into the object array which contains amount values
/// </summary>
/// <param name="size"> size varaible is to check the creating of new objects</param>
public void assignValues4()
{
int m = 0;
list[m] = new Values();
for (int i = 0; i < tempList3.Count();)
{
list[m].amount = tempList3[i];
i = i + 1;
m++;
if (m < size)
list[m] = new Values();
else
break;
}
}
/// <summary>
/// Method to assign the values of the fourth list into the object array which contains phost values
/// </summary>
/// <param name="size"> size varaible is to check the creating of new objects</param>
public void assignValues5()
{
int m = 0;
int i = 0;
list[m] = new Values();
for (i = 0; i < tempList4.Count();i++)
{
while (tempList4[i] != " " )
{
list[m].pHost = tempList4[i];
i++;
}
if (tempList4[i] == " " && i + 1 < tempList5.Count() && tempList4[i + 1] == " ")
{
m++;
i++;
list[m] = new Values();
list[m].pHost = tempList4[i];
}
m++;
if (m < size)
list[m] = new Values();
else
break;
}
}
/// <summary>
/// Method to assign the values of the fifth temp list into the object array which contains pCard values
/// </summary>
/// <param name="size"> size varaible is to check the creating of new objects</param>
public void assignValues6()
{
int m = 0;
int m2 = 0;
list[m] = new Values();
for (int i = 0; i < tempList5.Count() ; i++)
{
while (tempList5[i] != " ")
{
list[m].pCard = tempList5[i];
i++;
}
if (tempList5[i] == " " && i + 1 < tempList5.Count() && tempList5[i + 1] == " ")
{
if (m == m2 && m + 1 < size)
{
m++;
m2 = m;
}
list[m] = new Values();
list[m].pCard = " ";
m++;
if (m < size)
continue;
else
break;
}
m++;
m2 = m;
if (m < size)
list[m] = new Values();
else
break;
}
}
/// <summary>
/// Method to assign the values of the sixth temp list into the object array which contains the cslip details
/// </summary>
/// <param name="size"> size varaible is to check the creating of new objects</param>
public void assignValues7()
{
int m = 0;
int m2 = 0;
list[m] = new Values();
for (int i = 0; i < tempList6.Count();)
{
while (tempList6[i] != " ")
{
list[m].cslip = tempList6[i];
i++;
}
if (tempList6[i] == " " && i + 1 < tempList6.Count() && tempList6[i + 1] == " ")
{
if (m == m2 && m + 1 < size)
{
m++;
m2 = m;
}
list[m].cSlip = " ";
m++;
if (m < size)
continue;
else
break;
}
m++;
m2 = m;
if (m < size)
list[m] = new Values();
else
break;
}
}
public void show()
{
for(int i=0; i<size; i++)
{
Console.WriteLine(list[i].ID + " " + list[i].tName);
}
Console.ReadKey();
}
}
}
答案 0 :(得分:0)
您的代码写得很好,似乎线程有问题等待您完成所有任务(Task.WaitAll调用tasks / tasknew数组)。
例如,如果您要在主要功能中从ConsoleApplciation运行您的代码,您的流程将在您的任务之前结束。因此,简单的Console.ReadLine调用将解决您在此特定情况下的问题。
这样的事情:
Task[] task = new Task[6];
{
///...
Task.WaitAll(task);
Task[] tasknew = new Task[7];
{
//...
}
Task.WaitAll(tasknew);
//This will prevant you process to be closed, since it will wait for keyboard input.
Console.ReadKey();