2016-10-06 2 views
-1

스레딩에 대한 많은 설명을 읽었지 만 여전히 파악하기가 어렵습니다. 내 코드에서 시도한 및 이렇게 같은 오류가 발생합니다 : "추가 정보 : 크로스 스레드 작업이 유효하지 않습니다 :"dgvLocDatabase '스레드에서 만든 스레드가 아닌 다른 스레드에서 액세스 할 수있는 ". 아래는 내가 작성한 코드입니다. 다른 소스에서 오는 데이터를 2 개의 다른 DataGridview에 추가해야합니다.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"를 제거하고 난 그냥 "GetPcData을 실행하면 ;, 나는 에러가 발생하지 않는다 ("너무 전화 해 ")를 Messagebox.Show로 대체하고있는 경우 "그것 자체에, 나는 역시 오류를 얻지 않는다. 그래서 나는 그것이 문제를 일으키는 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

관련 문제