2012-09-25 10 views
0

나는 Parallel.ForEach에 대해 너무 혼란 스럽습니다.
당신은 Parallel.ForEach와 함께 아래의 코드를 재 작성하는 데 도움 주시기 바랍니다 것입니다 :Parallel.ForEach - ForEach 내부 목록 사용

#region Register 

    private void btnStartRegister_Click(object sender, EventArgs e) 
    { 
     if (backgroundWorker2.IsBusy) 
     { 
      btnStartRegister.Enabled = false; 
      lblStatusOfaccMValue.Text = "Canceling..."; 
      backgroundWorker2.CancelAsync(); 
     } 
     else 
     { 
      txtLogInRegister.Text = string.Empty; 
      btnStartRegister.Text = "Cancel"; 
      lblUserCreatedCountValue.Text = "---"; 
      lblStatusOfaccMValue.Text = "Running..."; 

      backgroundWorker2.RunWorkerAsync(); 
     } 
    } 

    private void backgroundWorker2_DoWork(object sender, DoWorkEventArgs e) 
    { 
     backgroundWorker2.ReportProgress(Convert.ToInt32(0)); 

     int UsersCount = int.Parse(txtUsersCount.Text); 
     UsersCreatedCount_Step = 0; 
     string path = Application.StartupPath; 
     string accfilePath = path + @"\acc.txt"; 
     string logfilePath = path + @"\log.txt"; 
     string Ok_ip_port = string.Empty; 
     string[] Separator = new string[] { "__" }; 
     int list_lines_acc_Current = -1; 

     string[] lines_acc = File.ReadAllLines(accfilePath); 
     List<string> list_lines_acc = new List<string>(lines_acc); 
     List<string> list_lines_acc_new = new List<string>(list_lines_acc); 

     foreach (string line_acc in list_lines_acc) 
     { 
      if (backgroundWorker2.CancellationPending) 
      { 
       e.Cancel = true; 
       break; 
      } 

      list_lines_acc_Current++; 
      string[] line_acc_ar = line_acc.Split(Separator, StringSplitOptions.None); 
      if (line_acc_ar.Length == 3) 
      { 
       string username = line_acc_ar[0]; 
       string password = line_acc_ar[1]; 
       string email = line_acc_ar[2]; 
       string[] email_ar = email.Split('@'); 
       email = email_ar[0] + "%40" + email_ar[1]; 


       list_lines_acc_new[list_lines_acc_Current] += "__" + txtSuffixURL.Text + "__" + txtServerNumber.Text + "__" + "127.0.0.1:2222"; 

       try 
       { 
        bool[] RegisterMethod_res = RegisterMethod(bla bla bla); 
        bool failed = RegisterMethod_res[0]; 
        bool world_full = RegisterMethod_res[1]; 
        if (!failed) 
        { 
         UsersCreatedCount_Step++; 
         backgroundWorker2.ReportProgress(Convert.ToInt32(UsersCreatedCount_Step * (100.0/UsersCount))); 
         list_lines_acc_new[list_lines_acc_Current] += "__" + "Y"; 
        } 
        else 
        { 
         if (world_full) 
         { 
          list_lines_acc_new[list_lines_acc_Current] += "__" + "N"; 
          e.Cancel = true; 
          break; 
         } 
         else 
         { 
          list_lines_acc_new[list_lines_acc_Current] += "__" + "N"; 
         } 
        } 

        File.WriteAllLines(accfilePath, list_lines_acc_new.ToArray()); 
       } 
       catch (Exception ex) 
       { 
        list_lines_acc_new[list_lines_acc_Current] += "__" + "N"; 

        File.WriteAllLines(accfilePath, list_lines_acc_new.ToArray()); 
       } 

       if (UsersCount == UsersCreatedCount_Step) 
       { 
        break; 
       } 
      } 
     } 

     File.WriteAllLines(accfilePath, list_lines_acc_new.ToArray()); 
    } 

    private bool[] RegisterMethod() 
    { 
     bla bla bla 
     ... 
     ... 
     return RegisterMethod_res; 
    } 

    private void backgroundWorker2_ProgressChanged(object sender, ProgressChangedEventArgs e) 
    { 
     progressBar2.Value = e.ProgressPercentage; 
     lblUserCreatedCountValue.Text = UsersCreatedCount_Step.ToString(); 
    } 

    private void backgroundWorker2_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e) 
    { 
     btnStartRegister.Text = "Start Register"; 
     btnStartRegister.Enabled = true; 

     if (e.Error != null) 
     { 
      MessageBox.Show(e.Error.Message); 
      return; 
     } 
     if (e.Cancelled) 
     { 
      lblStatusOfaccMValue.Text = "Cancelled..."; 
     } 
     else 
     { 
      lblStatusOfaccMValue.Text = "Completed"; 
     } 
    } 

    #endregion 

은 내가 Parallel.ForEachforeach (string line_acc in list_lines_acc) 라인을 교체합니다.
내가 그렇게 할 수 없었다 ...
당신이 읽기 및 쓰기에 대한 쓰기를위한 ACC 파일 ( acc.txt ) 일부 목록 (list_lines_acc + list_lines_acc_new이)가 볼 수있다.
항상 병렬 모드에서 문제가 있습니다.
편집 :
문제는이 라인에 관한 것입니다 ->

 if (UsersCount == UsersCreatedCount_Step) 
     { 
      break; 
     } 

내가 그 상태에 대한 그만하고 싶다.
하지만 병렬 모드에서 UsersCreatedCount_Step은 어떻게 작동합니까?

정말 도움이 될 것입니다.

미리 감사드립니다.

+3

전체 클래스가 아닌'foreach'가있는 메소드 만 보여주십시오. – Tudor

+0

하지만 다른 부분은 필요하다고 생각합니다. 내가 backgroundworker를 사용하고 그래서 내가 그 parallel.foreach 중지 버튼을 누르면 타격을 중지 할 수 있습니다 말씀 드리고자합니다. – MoonLight

+1

튜더가 맞습니다. 질문에 집중하십시오. 이것은 거의 읽을 수 없습니다. 그리고 항상 그렇듯이 : "병렬 모드에서 그들에 관한 문제가 있습니다"_ 설명하십시오. 어떤 문제들? –

답변

4

안전하게 진행할 수 있을지 확신하지 못합니다. 문제의 무리는 여러 스레드에서 동일한 파일에 쓰기를 시도하고 있다는 사실을 포함하여, 여기에 있습니다 : 부분은 잠금이 필요합니다뿐만 아니라, 당신이있는 경우도 성능을 저하시킬 것이다

File.WriteAllLines(accfilePath, list_lines_acc_new.ToArray()); 

기계 디스크.

+0

당신의 제안은 무엇입니까? (편집 및 답변 주셔서 감사합니다) – MoonLight

+0

@ MoonLight : 제 제안은이 경우 병렬 처리가 실제로 필요한지 먼저 생각하는 것입니다. 올바르게 수행하는 것이 상당히 지저분 해 보입니다. 이 코드가 더 빨리 필요합니까? – Tudor

+0

사실 자물쇠가 필요하지 않습니다. 그러나 그것을 덮어 씁니다. 'AppendAllLines()'가 그것을 할 수 있습니다. –