与Threadpool C#相关的问题。无法完成一个线程的执行

与Threadpool C#相关的问题。无法完成一个线程的执行,c#,multithreading,threadpool,stress-testing,C#,Multithreading,Threadpool,Stress Testing,我在下面有这个函数,我想了解它。还有,如果你有什么文件可以指给我看。我已经从msdn中了解了ManualResetEvent和ThreadPool public void GetParametersThreadPool() { var toProcess = 50; ManualResetEvent[] threadsActive = new ManualResetEvent[50]; for (int handleIndex = 0; handleIndex <

我在下面有这个函数,我想了解它。还有,如果你有什么文件可以指给我看。我已经从msdn中了解了ManualResetEvent和ThreadPool

public void GetParametersThreadPool()
{
    var toProcess = 50;
    ManualResetEvent[] threadsActive = new ManualResetEvent[50];
    for (int handleIndex = 0; handleIndex < 50; ++handleIndex)
    {
        threadsActive[handleIndex] = new ManualResetEvent(false);

        ThreadPool.QueueUserWorkItem(new WaitCallback(delegate(object state)
            {
                string reportUrl = TeamFoundationTestConfig.TeamFoundationReportPath("TaskGroupStatus");
                ReportUri reportUri = ReportUri.Create(reportUrl);
                Log.Message(TraceEventType.Information, "ReportUri = {0}".InvariantFormat(reportUri.UriString));
                IList<Parameter> parameters = this.RemoteReportingServiceFactory.CreateReportParameterProvider().GetParameters(reportUri, SessionContext);
                Assert.IsNotNull(parameters, "Assertion failed: Parameters cannot be null. GetParameters failed");
                Assert.IsTrue(parameters.Count > 0, "Assertion failed: No parameters available on the report page. GetParameters failed. Count = {0}".InvariantFormat(parameters.Count));
                if (Interlocked.Decrement(ref toProcess) == 0)
                {
                    threadsActive[handleIndex].Set();
                }
            }), null);

        //// Wait for all the threads to complete before starting the next set of requests.
        threadsActive[handleIndex].WaitOne(); 
    }   
}
public void GetParametersThreadPool()
{
var-toProcess=50;
ManualResetEvent[]threadsActive=新的ManualResetEvent[50];
对于(int-handleIndex=0;handleIndex<50;++handleIndex)
{
threadsActive[handleIndex]=新的手动重置事件(false);
ThreadPool.QueueUserWorkItem(新的WaitCallback(委托)(对象状态)
{
string reportUrl=TeamFoundationTestConfig.TeamFoundationReportPath(“TaskGroupStatus”);
ReportUri ReportUri=ReportUri.Create(reportUrl);
Message(TraceEventType.Information,“ReportUri={0}”.InvariantFormat(ReportUri.UriString));
IList parameters=this.RemoteReportingServiceFactory.CreateReportParameterExprovider().GetParameters(reportUri,SessionContext);
IsNotNull(参数,“断言失败:参数不能为null.GetParameters失败”);
IsTrue(parameters.Count>0,“断言失败:报告页上没有可用的参数。GetParameters失败。Count={0}”。不变量格式(parameters.Count));
if(互锁减量(参考TopProcess)==0)
{
threadsActive[handleIndex].Set();
}
}),空);
////等待所有线程完成,然后再启动下一组请求。
threadsActive[handleIndex].WaitOne();
}   
}
当我更新这行代码时:
ManualResetEvent[]threadsActive=newmanualresetevent[100]它给出的en异常仅表示小于64

目前,当我运行这个压力测试时,它挂在我进行日志记录的线路上,并且没有完成运行。我做错了什么

有没有更好的办法?另外,为了提供信息,我引用了stackoverflow中的另一个问题来创建这个函数


根据您可能想要使用的.NET版本,它随.NET 4一起提供。你的工具箱里也有

使用任务通常与

var t = Task.Factory.StartNew(() => { your code });
t.Wait();
如果出于任何原因,任务并行库不是一个选项,那么您可能需要考虑使用(在.NET4中)


至于64限制,这是操作系统强制执行的限制;遗憾的是,没有办法解决这个问题。

取决于您可能想要使用的.NET版本,它随.NET 4一起提供。你的工具箱里也有

使用任务通常与

var t = Task.Factory.StartNew(() => { your code });
t.Wait();
如果出于任何原因,任务并行库不是一个选项,那么您可能需要考虑使用(在.NET4中)


至于64限制,这是操作系统强制执行的限制;遗憾的是,没有办法解决这个问题。

正如建议的那样,如果可以,您可能应该使用任务。在它们可用之前,只需两个WaitHandle就可以实现您想要的功能。不是每个线程使用一个WaitHandle,而是为所有线程使用一个WaitHandle。waiting线程统计WaitHandle发出信号的次数,并仅在接收到所有信号后才继续执行。

正如建议的那样,如果可以,您可能应该使用Tasks。在它们可用之前,只需两个WaitHandle就可以实现您想要的功能。不是每个线程使用一个WaitHandle,而是为所有线程使用一个WaitHandle。waiting线程统计WaitHandle发出信号的次数,并仅在接收到所有信号时才继续。WaitOne阻塞当前线程,直到当前WaitHandle接收到信号,您正在编写多线程代码,但此方法实际上是sync方法

创建一个跟踪正在运行的任务数的变量:

var toProcess = 50;
创建一个信号而不是阵列

   ManualResetEvent signal = new ManualResetEvent(false);

for (int handleIndex = 0; handleIndex < 50; ++handleIndex)
    {


        ThreadPool.QueueUserWorkItem(new WaitCallback(delegate(object state)
            {
                string reportUrl = TeamFoundationTestConfig.TeamFoundationReportPath("TaskGroupStatus");
                ReportUri reportUri = ReportUri.Create(reportUrl);
                Log.Message(TraceEventType.Information, "ReportUri = {0}".InvariantFormat(reportUri.UriString));
                IList<Parameter> parameters = this.RemoteReportingServiceFactory.CreateReportParameterProvider().GetParameters(reportUri, SessionContext);
                Assert.IsNotNull(parameters, "Assertion failed: Parameters cannot be null. GetParameters failed");
                Assert.IsTrue(parameters.Count > 0, "Assertion failed: No parameters available on the report page. GetParameters failed. Count = {0}".InvariantFormat(parameters.Count));
                if (Interlocked.Decrement(ref toProcess) == 0)
                {
                    signal.Set();
                }
            }), null);


    }   

    signal.WaitOne();
ManualResetEvent信号=新的ManualResetEvent(假);
对于(int-handleIndex=0;handleIndex<50;++handleIndex)
{
ThreadPool.QueueUserWorkItem(新的WaitCallback(委托)(对象状态)
{
string reportUrl=TeamFoundationTestConfig.TeamFoundationReportPath(“TaskGroupStatus”);
ReportUri ReportUri=ReportUri.Create(reportUrl);
Message(TraceEventType.Information,“ReportUri={0}”.InvariantFormat(ReportUri.UriString));
IList parameters=this.RemoteReportingServiceFactory.CreateReportParameterExprovider().GetParameters(reportUri,SessionContext);
IsNotNull(参数,“断言失败:参数不能为null.GetParameters失败”);
IsTrue(parameters.Count>0,“断言失败:报告页上没有可用的参数。GetParameters失败。Count={0}”。不变量格式(parameters.Count));
if(互锁减量(参考TopProcess)==0)
{
signal.Set();
}
}),空);
}   
signal.WaitOne();
不要将signal.WaitOne()放在for循环的中,这样会阻塞线程


<>最后,考虑使用任务,如果你在.NET 3.5或更高版本

WITITON阻止当前线程,直到当前WaitHandle接收到一个信号,你正在编写多线程代码,但该方法实际上是同步方法

创建一个跟踪正在运行的任务数的变量:

var toProcess = 50;
创建一个信号而不是阵列

   ManualResetEvent signal = new ManualResetEvent(false);

for (int handleIndex = 0; handleIndex < 50; ++handleIndex)
    {


        ThreadPool.QueueUserWorkItem(new WaitCallback(delegate(object state)
            {
                string reportUrl = TeamFoundationTestConfig.TeamFoundationReportPath("TaskGroupStatus");
                ReportUri reportUri = ReportUri.Create(reportUrl);
                Log.Message(TraceEventType.Information, "ReportUri = {0}".InvariantFormat(reportUri.UriString));
                IList<Parameter> parameters = this.RemoteReportingServiceFactory.CreateReportParameterProvider().GetParameters(reportUri, SessionContext);
                Assert.IsNotNull(parameters, "Assertion failed: Parameters cannot be null. GetParameters failed");
                Assert.IsTrue(parameters.Count > 0, "Assertion failed: No parameters available on the report page. GetParameters failed. Count = {0}".InvariantFormat(parameters.Count));
                if (Interlocked.Decrement(ref toProcess) == 0)
                {
                    signal.Set();
                }
            }), null);


    }   

    signal.WaitOne();
ManualResetEvent信号=新的ManualResetEvent(假);
对于(int-handleIndex=0;handleIndex<50;++handleIndex)
{
ThreadPool.QueueUserWorkItem(新的WaitCallback(委托)(对象状态)
{
string reportUrl=TeamFoundationTestConfig.TeamFoundationReportPath(“TaskGroupStatus”);
ReportUri ReportUri=ReportUri.Create(reportUrl);
Log.Message(TraceEventType.Information,“ReportUri={