Task.WaitAll()不适用于第二组任务数组

时间:2016-10-13 06:15:59

标签: multithreading

我是线程新手,我目前使用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();
    }
}

}

1 个答案:

答案 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();