Foreach源分割成线样 [英] Divide Foreach into threads sample

查看:134
本文介绍了Foreach源分割成线样的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想要运行 SearchResultByOrderNumber(字符串订单号码) Foreach源法多线程。有在 OrderNumbers DataTable的10 OrderNumbers。而在搜索 OrderResults 的DataTable这些OrderNumbers,我想这些OrderNumbers分为五个线程。在每个线程将有两个搜索OrderNumbers。我怎样才能做到这一点的线程与Asp.Net 3.5框架?

我想,我必须重申我的问题。
我怎么可以把OrderNumbers到异步方法自动?
首先,我得到了 rowCount等。我要定义异步方法计数。然后,我将获得 rowsPerAsyncMethods rowCount等的分工与 asyncMethodCount

  rowsPerAsyncMethods = rowCount时/ asyncMethodCount

感谢您。

 无效的主要()
{    VAR MyTask1Caller =新Func键与LT;数据表>(MyTask1);
    VAR asyncResultMyTask1 = MyTask1Caller.BeginInvoke(NULL,NULL);
    VAR MyTask2Caller =新Func键与LT;数据表>(MyTask2);
    VAR asyncResultMyTask2 = MyTask2Caller.BeginInvoke(NULL,NULL);    数据表dtMyTask1 = MyTask1Caller.EndInvoke(asyncResultMyTask1);
    数据表dtMyTask2 = MyTask2Caller.EndInvoke(asyncResultMyTask2);
    Console.WriteLine(dtMyTask1);
    Console.WriteLine(dtMyTask2);
    asyncResultMyTask1.AsyncWaitHandle.WaitOne();
    asyncResultMyTask2.AsyncWaitHandle.WaitOne();
}公众诠释行数()
{
    DataTable的DT = OrderNumbers();
    诠释物品= dt.Rows.Count;    返回的物品;}
公开数据表MyTask1()
{
    数据表dtResult =新的DataTable();
    DataColumn的DC =新的DataColumn(订单号码的typeof(System.Int32));
    dtResult.Columns.Add(DC);
    DC =新的DataColumn(OrderResult,typeof运算(字符串));
    dtResult.Columns.Add(DC);    数据表dtOrders =新的DataTable();
    dtOrders = OrderNumbers();    VAR项目= dtOrders.AsEnumerable()
    。选择(N =将N)。取(3).CopyToDataTable();    的foreach(在items.AsEnumerable VAR为了())
    {        。字符串ORDERNUMBER =秩序[订单号码]的ToString();
        字符串orderResult = SearchResultByOrderNumber(订单编号);
        DataRow的博士= dtResult.NewRow();
        博士[订单号码] =订单号码;
        博士[OrderResult] = orderResult;
        dtResult.Rows.Add(DR);
    }    //Thread.Sleep(5000);
    返回dtResult;
}
公开数据表MyTask2()
{
    数据表dtResult =新的DataTable();
    DataColumn的DC =新的DataColumn(订单号码的typeof(System.Int32));
    dtResult.Columns.Add(DC);
    DC =新的DataColumn(OrderResult,typeof运算(字符串));
    dtResult.Columns.Add(DC);    数据表dtOrders =新的DataTable();
    dtOrders = OrderNumbers();    VAR项目= dtOrders.AsEnumerable()
    。选择(N =将N).Skip(3)。取(3).CopyToDataTable();    的foreach(在items.AsEnumerable VAR为了())
    {        。字符串ORDERNUMBER =秩序[订单号码]的ToString();
        字符串orderResult = SearchResultByOrderNumber(订单编号);
        DataRow的博士= dtResult.NewRow();
        博士[订单号码] =订单号码;
        博士[OrderResult] = orderResult;
        dtResult.Rows.Add(DR);
    }
    返回dtResult;
}    公共字符串SearchResultByOrderNumber(字符串订单号码)
    {        DataTable的DT =新的DataTable();
        DT = OrderResults();        VAR的查询=(从dt.AsEnumerable N()
                    其中,n [订单号码]。的ToString()== ORDERNUMBER
                    选择N [OrderResult]的ToString())FirstOrDefault()。
        返回查询;
    }    公开数据表OrderResults()
    {                DataTable的DT =新的DataTable(OrderResults);
                DataColumn的DC =新的DataColumn(订单号码的typeof(System.Int32));
                dt.Columns.Add(DC);
                DC =新的DataColumn(OrderResult,typeof运算(字符串));
                dt.Columns.Add(DC);                的for(int i = 1;我小于10;我++)
                {
                    DataRow的博士= dt.NewRow();
                    博士[订单号码] =我;
                    博士[OrderResult] = I +结果;
                    dt.Rows.Add(DR);
                }                返回DT;
    }
    公开数据表OrderNumbers()
    {                DataTable的DT =新的DataTable(OrderNumbers);
                DataColumn的DC =新的DataColumn(订单号码的typeof(System.Int32));
                dt.Columns.Add(DC);                的for(int i = 0;我小于10;我++)
                {
                    DataRow的博士= dt.NewRow();
                    博士[订单号码] =我;
                    dt.Rows.Add(DR);
                }                返回DT;
    }


解决方案

如果.NET 4.0可用,则只需使用Parallel.ForEach结构。

如果不是,在并行处理,这是因为使用线程池类,与同步的一些其他工作一样简单:

  INT任务= 0; //跟踪活动任务数
对象更衣室=新的对象(); //同步对象的foreach(在dtOrders.AsEnumerable变种order1())
{
    锁(柜)的任务++; //添加新任务
    VAR为了= order1; //本地副本,以避免数据争
    ThreadPool.QueueUserWorkItem(
       O =>
       {
            。字符串ORDERNUMBER =秩序[订单号码]的ToString();
            字符串orderResult = SearchResultByOrderNumber(订单编号);
            DataRow的博士= dtResult.NewRow();
            博士[订单号码] =订单号码;
            博士[OrderResult] = orderResult;            锁(柜)//更新共享数据结构和信号端接
            {
                dtResult.Rows.Add(DR);
                任务 - ;
                Monitor.Pulse(柜);
            }
       });
}//屏障等待所有任务完成
锁(柜)
{
   同时(任务大于0)Monitor.Wait(柜);
}

I want to run "SearchResultByOrderNumber(string orderNumber)" method in Foreach with multithreading. There are ten OrderNumbers in OrderNumbers Datatable. While searching these OrderNumbers in OrderResults Datatable, I want to divide these OrderNumbers into five threads. In each thread there will be two search for OrderNumbers. How can I do this threading with Asp.Net 3.5 Framework ?

I think, I must renew my question. How can I divide "OrderNumbers" into Async methods automatically? Firstly, I got rowCount. I am going to define Async method count. Then I will get rowsPerAsyncMethods by division of rowCount with asyncMethodCount.

rowsPerAsyncMethods = rowCount / asyncMethodCount

Thank you.

void Main()
{   

    var MyTask1Caller = new Func<DataTable>(MyTask1);
    var asyncResultMyTask1 = MyTask1Caller.BeginInvoke(null, null);
    var MyTask2Caller = new Func<DataTable>(MyTask2);
    var asyncResultMyTask2 = MyTask2Caller.BeginInvoke(null, null);

    DataTable dtMyTask1 = MyTask1Caller.EndInvoke(asyncResultMyTask1);
    DataTable dtMyTask2 = MyTask2Caller.EndInvoke(asyncResultMyTask2);
    Console.WriteLine("dtMyTask1");
    Console.WriteLine("dtMyTask2");
    asyncResultMyTask1.AsyncWaitHandle.WaitOne();
    asyncResultMyTask2.AsyncWaitHandle.WaitOne();


}

public int RowCount()
{
    DataTable dt = OrderNumbers();
    int items = dt.Rows.Count;

    return items;

}


public DataTable MyTask1()
{
    DataTable dtResult = new DataTable();
    DataColumn dc = new DataColumn("OrderNumber", typeof(System.Int32));
    dtResult.Columns.Add(dc);
    dc = new DataColumn("OrderResult", typeof(string));
    dtResult.Columns.Add(dc);

    DataTable dtOrders = new DataTable();
    dtOrders = OrderNumbers();

    var items = dtOrders.AsEnumerable()
    .Select(n => n).Take(3).CopyToDataTable();

    foreach(var order in items.AsEnumerable())
    {   

        string orderNumber = order["OrderNumber"].ToString();
        string orderResult = SearchResultByOrderNumber(orderNumber);
        DataRow dr = dtResult.NewRow();
        dr["OrderNumber"] = orderNumber;
        dr["OrderResult"] = orderResult;
        dtResult.Rows.Add(dr);
    }

    //Thread.Sleep(5000);       
    return dtResult;
}


public DataTable MyTask2()
{
    DataTable dtResult = new DataTable();
    DataColumn dc = new DataColumn("OrderNumber", typeof(System.Int32));
    dtResult.Columns.Add(dc);
    dc = new DataColumn("OrderResult", typeof(string));
    dtResult.Columns.Add(dc);

    DataTable dtOrders = new DataTable();
    dtOrders = OrderNumbers();

    var items = dtOrders.AsEnumerable()
    .Select(n => n).Skip(3).Take(3).CopyToDataTable();

    foreach(var order in items.AsEnumerable())
    {   

        string orderNumber = order["OrderNumber"].ToString();
        string orderResult = SearchResultByOrderNumber(orderNumber);
        DataRow dr = dtResult.NewRow();
        dr["OrderNumber"] = orderNumber;
        dr["OrderResult"] = orderResult;
        dtResult.Rows.Add(dr);
    }


    return dtResult;
}

    public string SearchResultByOrderNumber(string orderNumber)
    {

        DataTable dt = new DataTable();
        dt = OrderResults();

        var query = (from n in dt.AsEnumerable()
                    where n["OrderNumber"].ToString() ==orderNumber
                    select n["OrderResult" ].ToString()).FirstOrDefault();
        return query;
    }

    public DataTable OrderResults()
    {

                DataTable dt = new DataTable("OrderResults");
                DataColumn dc = new DataColumn("OrderNumber", typeof(System.Int32));
                dt.Columns.Add(dc);
                dc = new DataColumn("OrderResult", typeof(string));
                dt.Columns.Add(dc);

                for(int i=1; i<10; i++)
                {
                    DataRow dr = dt.NewRow();
                    dr["OrderNumber"] = i;
                    dr["OrderResult"] =i +" Result";
                    dt.Rows.Add(dr);
                }

                return dt;
    }


    public DataTable OrderNumbers()
    {

                DataTable dt = new DataTable("OrderNumbers");
                DataColumn dc = new DataColumn("OrderNumber", typeof(System.Int32));
                dt.Columns.Add(dc);

                for(int i=0; i<10; i++)
                {
                    DataRow dr = dt.NewRow();
                    dr["OrderNumber"] = i;
                    dt.Rows.Add(dr);
                }

                return dt;
    }

解决方案

If .NET 4.0 is available you can just use the Parallel.ForEach construct.

If not, processing this in parallel is as simple as using the ThreadPool class, with some additional work for synchronization:

int tasks = 0; // keep track of number of active tasks
object locker = new object(); // synchronization object

foreach(var order1 in dtOrders.AsEnumerable())
{
    lock(locker) tasks++; // added a new task
    var order = order1; // local copy to avoid data races
    ThreadPool.QueueUserWorkItem(
       o =>
       {          
            string orderNumber = order["OrderNumber"].ToString();
            string orderResult = SearchResultByOrderNumber(orderNumber);
            DataRow dr = dtResult.NewRow();
            dr["OrderNumber"] = orderNumber;
            dr["OrderResult"] = orderResult;

            lock(locker) // update shared data structure and signal termination
            {
                dtResult.Rows.Add(dr);
                tasks--;
                Monitor.Pulse(locker);
            }                
       });
}

// barrier to wait for all tasks to finish
lock(locker)
{
   while(tasks > 0) Monitor.Wait(locker); 
}

这篇关于Foreach源分割成线样的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆