2016-12-19 25 views
-1

UIからメソッドを呼び出すと、メソッドが終了するのに時間がかかる UIをフリーズし、何が起きているかをユーザーフォームに知らせないようにします。バックグラウンドスレッドからdatagridviewを更新する

「datagridview」のカラム(ステータス)をUIのフィードバックユーザに更新して、どのIPが接続されていて、どれが未接続であるかを知ろうとしていますが、メソッドが終了するまでUIがフリーズする前に言いました。

提案の1つはスレッドを使用することでしたが、私はそれを行いましたが、私の問題は解決されていませんでした。

public void PatchUpdates() 
    { 
     try 
     { 
      foreach (DataGridViewRow OfficeListRow in DGV_OfficeList.Rows) 
      { 
       string OfficeIPAddress = OfficeListRow.Cells[3].Value.ToString(); 

       foreach (DataGridViewRow FileListRow in DGV_FileList.Rows) 
       { 
        string SoruceFileNamePath = FileListRow.Cells[4].Value.ToString(); 
        string DestinationFileNamePath = @"\\" + OfficeIPAddress + @"\usb1_1\test\" + Path.GetFileName(SoruceFileNamePath); 

        Thread foregroundthread = new Thread(() => CheckOffice(OfficeIPAddress)); 
        foregroundthread.Start(); 

        //check if connection to remote server is available 
        if (CheckOffice(OfficeIPAddress) == 1) 
        { 
         DGV_OfficeList[4, DGV_OfficeList.CurrentCell.RowIndex].Value = "Connected"; 
         //file.copy(sorucefilenamepath, destinationfilenamepath, true); //copy files... 
        } 
        else if (CheckOffice(OfficeIPAddress) == 0) 
        { 
         DGV_OfficeList[4, DGV_OfficeList.CurrentCell.RowIndex].Value = "disconnected"; 
        } 
       } 
      } 
     } 
     catch (Exception ex) 
     { 
      MessageBox.Show(ex.Message, "Error", MessageBoxButtons.OK, MessageBoxIcon.Error); 
     } 
    } 

ピング法

public int CheckOffice(string _ipAddress) 
    { 
     int timeout = 120; 
     string data = "PingTestData"; 
     byte[] buffer = Encoding.ASCII.GetBytes(data); 

     Ping PingSender = new Ping(); 
     PingOptions options = new PingOptions(); 

     options.DontFragment = true; 

     PingReply reply = PingSender.Send(_ipAddress, timeout, buffer, options); 

     if (reply.Status == IPStatus.Success) 
     { 
      return 1; 
     } 
     else 
     { 
      return 0; 
     } 
    } 

答えて

0

一度新しいスレッドで二回GUIスレッドで、CheckOfficeを3回呼び出している瞬間。新しいスレッドで計算された戻り値は使用されません。

交換してみてください:

   Thread foregroundthread = new Thread(() => CheckOffice(OfficeIPAddress)); 
       foregroundthread.Start(); 

       //check if connection to remote server is available 
       if (CheckOffice(OfficeIPAddress) == 1) 
       { 
        DGV_OfficeList[4, DGV_OfficeList.CurrentCell.RowIndex].Value = "Connected"; 
        //file.copy(sorucefilenamepath, destinationfilenamepath, true); //copy files... 
       } 
       else if (CheckOffice(OfficeIPAddress) == 0) 
       { 
        DGV_OfficeList[4, DGV_OfficeList.CurrentCell.RowIndex].Value = "disconnected"; 
       } 

 var task = Task.Run(() => 
      { 
       var result = CheckOffice(OfficeIPAddress); 

       this.BeginInvoke((Action)(() => 
       { 
        if (result == 1) 
        { 
         DGV_OfficeList[4, DGV_OfficeList.CurrentCell.RowIndex].Value = "Connected"; 
         //file.copy(sorucefilenamepath, destinationfilenamepath, true); //copy files... 
        } 
        else if (result == 0) 
        { 
         DGV_OfficeList[4, DGV_OfficeList.CurrentCell.RowIndex].Value = "disconnected"; 
        } 
       })); 
      } 
     ); 

これはむしろ、あなただけの非同期ロジックを起動したい場合は、より良い練習で明示的にスレッド、よりタスクを使用し、その後にBeginInvokeメソッドを使用してGUIスレッドを使用してGUIに更新を適用します。そうしないと、スレッドセーフではないDataGridViewコントロールで問題が発生します。 WinformsウィンドウまたはコントロールでBeginInvokeを定義するか、Dispatcherを調べる必要があります。

+0

ありがとうございました。まずは... 'Task.Run()'はドットネット4を使用しているため動作しません。この問題について検索したときに「Task.Factory.StartNew 'をinstedで使用することはできますが、リスクが非常にあります>>再度教えてくれたHELPに感謝します – sam

関連する問題