Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/308.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 如何在线程中旋转这两个进程?_C#_Multithreading - Fatal编程技术网

C# 如何在线程中旋转这两个进程?

C# 如何在线程中旋转这两个进程?,c#,multithreading,C#,Multithreading,我有一个方法,从两个区域加载数据。目前,其处理区域1,然后处理区域2。所以它是单线程的。我需要同时做这些事情。这是当前代码。请告诉我需要做什么 在这里输入代码 --哇,问题多了。我必须在这里对我的答案做出一些假设: 您正在使用.NET4.0 ProcessMessage方法不访问任何受保护的共享状态,这些状态将受到多个线程并发调用的影响 Logger.Log也不会访问任何不受保护的共享状态,这些状态会受到多个线程并发调用的影响 有了这些,你的朋友是: Parallel.Invoke( (

我有一个方法,从两个区域加载数据。目前,其处理区域1,然后处理区域2。所以它是单线程的。我需要同时做这些事情。这是当前代码。请告诉我需要做什么

在这里输入代码
--

哇,问题多了。我必须在这里对我的答案做出一些假设:

  • 您正在使用.NET4.0
  • ProcessMessage方法不访问任何受保护的共享状态,这些状态将受到多个线程并发调用的影响
  • Logger.Log也不会访问任何不受保护的共享状态,这些状态会受到多个线程并发调用的影响
  • 有了这些,你的朋友是:

    Parallel.Invoke(
        () =>
        {
           string region1 = Config.AppSettings["Region1"];
    
           if(region1.Trim().Length > 0)
           {
                string region1ReturnMessage = ProcessMessage(string.Format(queueName, region1));
                Logger.Log(region1ReturnMessage);
           }
        },
        () =>
        {
           string region2 = Config.AppSettings["Region2"];
    
           if(region2.Trim().Length > 0)
           {
                string region2ReturnMessage = ProcessMessage(string.Format(queueName, region2));
                Logger.Log(region2ReturnMessage);
           }
        });
    

    此外,需要考虑的是,如果由于这些检查而不实际调用特定区域的PurrimeMeor是常见的情况,那么在主线程上进行这些检查是有意义的,而不是总是调度多个调用。在这种情况下,您需要下拉到纯TPL任务管理代码中,并仅动态分配所需的任务数量。只有当这些代码将在某种服务进程本身的负载下执行时,我才会麻烦地这样做。否则,这是一个过早的优化。如果您想了解原始TPL方法的外观,请在评论中告诉我,我将提供一个示例。

    如果您使用的是旧版本的.net,除了这里的@Drew Marsh answer,您还可以使用
    thread
    类或
    ThreadPool.QueueUserWorkItem
    调用新线程中的每个操作

    //example using Thread class
    new Thread(() =>
    {
        if (Region1.Trim().Length > 0)
        {                
            returnMessage = ProcessMessage(string.Format(queueName, Region1));
            Logger.Log(returnMessage);
        }
    }) { IsBackground = true }.Start();
    
    //example using ThreadPool
    ThreadPool.QueueUserWorkItem(new WaitCallback((_) =>
    {
        if (Region2.Trim().Length > 0)
        {
            returnMessage = ProcessMessage(string.Format(queueName, Region2));
            Logger.Log(returnMessage);
        }
    }));
    

    无论如何,如果你在应用程序中更新了<代码>区域1>代码>或代码>区域2>代码>,那么你应该考虑使用同步机制来访问它们,如<代码>锁…< /P>我认为你需要在LAMBDAS中放置<代码> IF-(<)/C> > s。@亨克Heltman -当然,好的调用。更新了示例以包含所有逻辑,因此更清晰。感谢您的回复。是的,我正在使用.NET4.0。我认为ProcessMessage和Logger.log不会访问任何不受保护的数据。但我会进一步调查。代码在服务中。ProcessMessage检查系统是否已关闭以及其他内容。我无法使用System.Threading.Tasks来使用Parallel.Invoke。我无法使用System.Threading.Tasks来使用Parallel.Invoke。我需要添加任何引用吗?不,这些类位于mscorlib中。仔细检查以确保您的项目设置为使用“.NET Framework 4”。感谢您的回复。我只看到了一个使用区域的地方:如下所示。我需要用这把锁吗?字符串Region1=Config.AppSettings[“Region1”];字符串Region2=Config.AppSettings[“Region2”];OutputQueue=mqQMgr.AccessQueue(string.Format(Config.AppSettings[“MQSIInboundQueueName”],shawRegion1),不可删除)@Ree:如果您只使用这里的区域,那么我认为您没有锁定是安全的,但是您必须确保您没有更新

    ProcessMessage
    方法中的任何共享变量或数据,如果您没有更新任何共享数据或变量,则不必在此处使用
    锁定
    或其他同步机制。@Ree:在注释中查看您更新的代码:我不知道
    mqmgr.AccessQueue
    中的代码是什么,它确实依赖于它。注释中的代码可以忽略。我在一个测试项目文件中发现了这一点。因此,除了在RProcess()方法中,我们不会在其他任何地方更新区域。看起来Processmethod正在更新共享数据和变量。我需要在哪里使用锁和同步?谢谢
    //example using Thread class
    new Thread(() =>
    {
        if (Region1.Trim().Length > 0)
        {                
            returnMessage = ProcessMessage(string.Format(queueName, Region1));
            Logger.Log(returnMessage);
        }
    }) { IsBackground = true }.Start();
    
    //example using ThreadPool
    ThreadPool.QueueUserWorkItem(new WaitCallback((_) =>
    {
        if (Region2.Trim().Length > 0)
        {
            returnMessage = ProcessMessage(string.Format(queueName, Region2));
            Logger.Log(returnMessage);
        }
    }));