2016-02-22 26 views
1

我是新來的C#編程,我有一個任務,使一個進程從單線程多線程。我正在使用C#3.5版本並在代碼中實現threadpool。我已經搜索了關於線程池並做了一些更改,但它不起作用。當我再次在互聯網上搜索時,我認爲我只寫了部分代碼,只排隊用戶工作項,我不知道如何執行這些線程。如何在C#中排隊用戶工作項之後執行線程池?

這裏顯示的是我寫的代碼,如果代碼錯誤請不要猶豫糾正我,我對C#編碼非常陌生。

ThreadPool.SetMaxThreads(6, 6); 

try 
{ 
    // Assign the values to the report parameters 
    for (int i = 0; i < aq.Count; i++) 
    { 
     object j = aq[i]; 
     ThreadPool.QueueUserWorkItem(new WaitCallback(process), j); 
    } 
}    
    private void process(object i) 
    { 

     List<Report> aq = new List<Report>(); 
     ReportEnv env = null; 
     ParameterValue[] paramval; 

     List<Report> list = new List<Report>(); 
     Report al = null; 

     using (OleDbDataAdapter oleDA = new OleDbDataAdapter()) 
     using (DataTable dt = new DataTable()) 
     { 
      oleDA.Fill(dt, i); 

      foreach (DataRow _row in dt.Rows) 
      { 
       al = new Report(); 

       al.EmailAttachmentMsg = _row["AttachmentMsg"].ToString(); 
       al.reportName = _row["Repo"].ToString(); 
       al.AccountNumber = _row["Number"].ToString(); 
       al.AccountGroupCode = _row["GroupCode"].ToString(); 
       al.EmailTo = _row["To"].ToString().Split(';'); 
       al.ReportScheduleId = _row["ReportScheduleId"].ToString(); 
       al.Frequency = _row["Frequency"].ToString(); 
       al.ColcoContactTelephone = _row["ColcoContactTelephone"].ToString(); 

       list.Add(al); 
      } 
     } 
     // aq = Populatereport(Dts.Variables["vnSource_SQL_Result"].Value); 
     env = PopulateEnvironment(Dts.Variables["vnEnvironment"].Value); 
     aq = list; 


     paramval = new ParameterValue[2]; 
     paramval[0] = new ParameterValue(); 
     paramval[0].Name = "PRM_CustomerDetails"; 
     paramval[0].Value = aq[0].AccountNumber; 
     paramval[1] = new ParameterValue(); 
     paramval[1].Name = "PRM_Startdate"; 
     paramval[1].Value = aq[0].StartDate; 


     //Rendering the report begins 

     ReportExecutionService rs = new ReportExecutionService(); 
     rs.Credentials = System.Net.CredentialCache.DefaultCredentials; 
     rs.Url = env.SSRSServerUrl.ToString(); 


     //Load the report options 
     rs.LoadReport(aq[0].ReportPath, null); 
     rs.SetExecutionParameters(paramval, aq[0].CultureCode); 



     // Set the filename 

     String filename = aq[0]. Number + "_" + env.Code + "_" + "_" + aq[0].Name + 
      DateTime.UtcNow.ToString("_dd-MM-yyyy_hh-mm-ss.fff"); 

     //Render the report and generate pdf 
     Byte[] results; 
     string encoding = String.Empty; 
     string mimeType = String.Empty; 
     string extension = String.Empty; 
     Warning[] warnings = null; 
     string[] streamIDs = null; 
     string deviceInfo = null; 
     results = rs.Render(aq[0].ReportFormat, deviceInfo, out extension, out encoding, out mimeType, out warnings, out streamIDs); 


     //Write the file into the directory 
     using (FileStream stream = File.OpenWrite(@env.wipPath + filename)) 
     { 

      stream.Write(results, 0, results.Length); 
     } 


      if (SendEmail(env.From, aq[0].To, env.Subject, aq[0].Attachment, env.Server, false, filename, env.TimeOut) == true) 
      { 
       // Move report file from WIP to Processed 
       File.Move(@env.oldPath + filename, @env.newPath + filename); 
       } 


      } 
+0

這看起來並不像部分代碼給我。它應該工作。什麼表明它不起作用?你在process()上做了一個斷點嗎? – Tyress

+0

你在等待主線程嗎?我假設如此。如果不是,排隊的線程可能永遠不會執行。 – Venki

+0

請參閱此http://stackoverflow.com/questions/14515207/whats-the-proper-way-to-use-a-threadpool – Venki

回答

0

您不必再做任何事情。通過調用QueueUserWorkItem表示您想要在由線程池管理的線程中執行一個給定方法。但是,您不能保證它會立即執行,並且它是線程池的工作方式。當線程池線程可用時,您的方法將被執行。

在代碼的第一行中,您調用ThreadPool.SetMaxThreads(6, 6);因爲不會有超過6個線程池線程同時處於活動狀態。所有在線程池中執行某些事情的請求都會排隊。所以,也許你提出了很多要求,其中一些只是等待輪到他們。

此外,您必須記住,可能有另一個代碼也使用線程池。在這種情況下,您的請求需要爭用線程池線程。

UPDATE(討論後):

嘗試把一個斷點process方法內。調試器將停在那裏,它會證明process方法真的被執行。但是,您的代碼中可能存在一些錯誤,這就是爲什麼您看不到電子郵件被設置的原因

+0

我的代碼中的方法過程需要參數並以PDF格式呈現基於參數,並將發送郵件,並將該pdf文件從一個路徑移動到另一個路徑。我的問題是它在上面的代碼循環,但它不會去方法過程做如上所述的gerating pdf和郵件。 –

+0

你怎麼知道_process_方法沒有被執行?請附上此方法的代碼。 –

+0

@SAILENDRA - 謝謝,你能否回答你如何知道_process_沒有執行?你有沒有試圖在這個方法中加入一個斷點? –

0

我認爲您的代碼可能無法執行的一個原因是您在線程之間有某種race condition執行和你的程序結束。你的代碼有多長?如果您剛剛開始學習C#,我有一種感覺,您正在編寫一個控制檯應用程序,並且您的代碼主要位於Main()方法中,並由幾行代碼組成。如果您在短應用程序上執行ThreadPool.QueueUserWorkItem(),並且立即到達Main()方法的末尾,那麼您的代碼可能永遠無法執行!

爲了避免這種情況,你可以增加睡眠一秒鐘Main()方法結束之前,例如:

Thread.Sleep(1000); 
+1

如果您想等待某些內容,請勿使用「睡眠」。對於正常的線程使用'加入'。等待線程池中的所有線程都有點複雜。但是這裏的第二個答案是非常全面的:http://stackoverflow.com/questions/6529659/wait-for-queueuserworkitem-to-complete(好的思考程序停止在工作完成之前btw!) –

+0

沒有我的代碼相當大大,上面提到的方法過程採用這些參數並呈現PDF格式的報告並將其郵寄給它。執行不會處理方法。 –

+0

@RoyT。我想我認爲他是一個新手,所以我提出了一個簡單的解決方法,儘管現在想想它,但在任何情況下建議使用「睡眠」可能不是一件好事:P – Tyress

相關問題