这个Parallel.For代码有什么问题?

时间:2011-04-09 09:18:10

标签: multithreading c#-4.0 .net-4.0

这是我想要运行的代码。

Parallel.For(1, itemCount, 1, () =>
                    {
                     return new ThreadLocalStateCache()
                     {
                         //assigning values to local variables
                         Receipient = serMailObj.ReceipientList.Dequeue(), //get a single recepeint for the email
                         mail = serMailObj.Email, //Object of type MailMessage
                         client = client //object of type SmtpClient
                     };
                }
     , (i, loopState) =>
     {
         doWork(i, loopState.ThreadLocalState);

     });
                }
//class to store local vairables for each thread
public class ThreadLocalStateCache
    {
        public KeyValuePair<string, string> Receipient { get; set; }

        public MailMessage mail { get; set; }

        public SmtpClient client { get; set; }
    }

private static void doWork(int instance, ThreadLocalStateCache threadInstance)
        { 
           //send mail
        }

并继续说

无法从用法中推断出方法'System.Threading.Tasks.Parallel.For(long,long,System.Func,System.Func,System.Action)'的类型参数。尝试明确指定类型参数。

我在互联网上找不到任何资源,清楚地解释了如何使用parallel.for和线程局部变量。我正在尝试处理长长的电子邮件收件人列表并向他们发送邮件。请告诉我如何使用parallel.for。

编辑1:我在阅读本文后试用此代码http://www.lovethedot.net/2009/02/parallelfor-deeper-dive-parallel.html

1 个答案:

答案 0 :(得分:1)

从.NET 4中删除了带有作为第三个参数的步骤的Parallel.For重载;请参阅http://blogs.msdn.com/b/pfxteam/archive/2009/05/26/9641563.aspx的评论。

因此,您使用5个参数的呼叫将解析为this overload

For<TLocal>(Int32, Int32, Func<TLocal>, Func<Int32, ParallelLoopState, TLocal, TLocal>, Action<TLocal>)

显然,编译器无法匹配参数的类型。

无论如何步骤为1,只需将其删除即可 然后,您将需要修复必须具有三个参数的主体委托(因为线程局部变量现在与循环状态对象分开),并添加另一个委托,该委托将应用于线程局部变量以进行最终计算。最后,它应该是这样的:

Parallel.For( 1, itemCount,
              () =>
              { return new ThreadLocalStateCache() 
                           { 
                               Receipient = serMailObj.ReceipientList.Dequeue(),
                               mail = serMailObj.Email,
                               client = client
                           }; 
              },
              (i, loopState, threadLocal ) => 
              { 
                  doWork(i, threadLocal);
                  return threadLocal;
              },
              (threadLocal) => {}
            );