2016-10-06 4 views
-1

スレッドに関する多くの説明を読んだことがありますが、まだ把握するのは非常に難しいです。私は自分のコードで試してみましたが、エラーが発生しました:"その他の情報:クロススレッド操作が有効でない:コントロール 'dgvLocDatabase'が、作成されたスレッド以外のスレッドからアクセスされました。"。以下は私が作成したコードです。異なるソースからのデータを2つの異なるデータグリッドビューに追加する必要があります。私はParallel.Invokeから「GetPcData」を削除し、(「あまりにも私を呼び出す」)Messagebox.Showでそれを代用した場合;,私はエラーを取得しないと私はちょうど「GetPcDataを実行する場合Parallel.Invokeを使用してクロススレッド操作が無効である

private void btnCountRecord_Click(object sender, EventArgs e) 
{ 
    CountRecord(); 

    Parallel.Invoke(
     GetDevData, 
     GetPcData 
     ); 
} 



private void GetDevData() 
{ 

    if (bIsConnected == false) 
    { 
     MessageBox.Show(@"Please connect the device first", @"Error"); 
     return; 
    } 

    var sdwEnrollNumber = ""; 
    var idwTMachineNumber = 0; 
    var idwEMachineNumber = 0; 
    var idwVerifyMode = 0; 
    var idwInOutMode = 0; 
    var idwYear = 0; 
    var idwMonth = 0; 
    var idwDay = 0; 
    var idwHour = 0; 
    var idwMinute = 0; 
    var idwSecond = 0; 
    var idwWorkcode = 0; 

    var idwErrorCode = 0; 
    var iGlCount = 0; 
    var iIndex = 0; 

    dgvDevDatabase.Rows.Clear(); 


    axCZKEM1.EnableDevice(iMachineNumber, false); //disable the device 
    if (axCZKEM1.ReadGeneralLogData(iMachineNumber)) //read all the attendance records to the memory 
    { 
     lblProgressBar.Text = @"Loading data. Please wait..."; 
     progBar.Visible = true; 
     progBar.Maximum = _gRecCount; 
     progBar.Minimum = 1; 
     progBar.Value = 1; 
     progBar.Step = 1; 

     while (axCZKEM1.SSR_GetGeneralLogData(iMachineNumber, out sdwEnrollNumber, out idwVerifyMode, 
        out idwInOutMode, out idwYear, out idwMonth, out idwDay, out idwHour, out idwMinute, out idwSecond, ref idwWorkcode))//get records from the memory 
     { 
      iGlCount++; 
      var bioId = sdwEnrollNumber; 
      var timeLog = idwYear + "-" + idwMonth + "-" + idwDay + " " + idwHour + ":" 
       + idwMinute + ":" + idwSecond; 
      dgvDevDatabase.Rows.Add(bioId, timeLog); 
      progBar.PerformStep(); 
     } 
     if (progBar.Value == _gRecCount) lblProgressBar.Text = @""; 
    } 
    else 
    { 
     Cursor = Cursors.Default; 
     axCZKEM1.GetLastError(ref idwErrorCode); 

     if (idwErrorCode != 0) 
     { 
      MessageBox.Show(@"Reading data from device failed. ErrorCode: " + idwErrorCode, @"Error"); 
     } 
     else 
     { 
      MessageBox.Show(@"No data from terminal to return", @"Error"); 
     } 
    } 
    axCZKEM1.EnableDevice(iMachineNumber, true);//enable the device 
} 

private void GetPcData() 
     { 
      var tda = new TimeLogDataAccess(); 
      _rdr = tda.GetAllLogs(); 
      while (_rdr.HasRows && _rdr.Read()) 
      { 
       dgvLocDatabase.Rows.Add(_rdr["bio_id"].ToString(), _rdr["time_log"].ToString()); 
      } 
     } 

"それは自分自身で、私はあまりにもエラーを取得しません。だから私はそれが問題を引き起こしているParallel.Invokeの "GetPcData"だと思います。

私が間違っていることを教えてください。あなたがこのparallel.invokeまたはthreadingをもっと私に説明できるかどうか教えてください。ありがとうございました。

答えて

0

問題は、スレッド以外のスレッドでUIを変更しようとしていることです。UIは作成されました。 SynchronizationContextクラス(https://msdn.microsoft.com/en-us/library/system.threading.synchronizationcontext(v=vs.110).aspx)を見て、次を試してください。 新しいスレッドを呼び出す前に、 SynchronizationContext.Current を変数に割り当ててください。新しいスレッドを開始し、UIを更新する場合は、

myContext.Post(cb => { doSomethingOnUi(); }, null); 

を呼び出し、問題が解決するかどうか確認してください。

+0

ありがとうございます。私はそれについてどうやって行くのか分からない。どうやったらそれが私にはもっと合理的かを教えてください。 – Ibanez1408

+0

SynchronizationContextに関する私の編集を参照してください – samwise

関連する問題