2016-06-22 8 views
1

.NET4를 사용하여 C#, 나는 winform에 그리드가 있습니다. 프로세스 버튼을 누르면 각 행에서 몇 단계 만 수행하여 적시에 작업을 수행 한 다음 결과로 행을 업데이트해야합니다. 이렇게하면 다음 행이 처리되는 동안 사용자가 진행률을 볼 수 있습니다. 사용자가 취소하거나 양식을 닫을 경우 현재 행의 프로세스를 완료 한 다음 양식을 중단하거나 닫아야합니다. 내 연구를 바탕으로, 여기에 내가 생각해 낸 것입니다. 2 문제가 남아 있습니다. 양식을 닫기 전에 스레드를 중지하십시오.

delegate void OperateGridMethodDelegate(); 
delegate void UpdateProgressDelegate(int rowIndex, string msg); 
bool isCancelled = false; 


private void ButtonOne_Click(object sender, EventArgs e) 
{ 
    isCancelled=false; 
    OperateGridMethodDelegate delegate = new OperateGridMethodDelegate(LongProcess);` 
    delegate.BeginInvoke(null,null); 

} 

private void ButtonTow_Click(object sender, EventArgs e) 
{ 

    MyButtonOne.Enabled=false; 
    isCancelled=true; 

} 

private void LongProcess() 
{ 

    foreach (DataRow row in dataTableOne.Rows) 
    { 
     //Do Lengthy Process 

     DisplayResult(rowIndex, "this is result of operation"); 
     if(isCancelled) 
     { 
      MyButtonOne.Enabled=true; 
      break; 

     } 

    } 

} 

private void DisplayResult(int rowIndex,string message) 
{ 

    if(myGrid.InvokeRequired == false) 
    { 

     myGrid.Rows[rowIndex].value = message; 

    } 

    else 
    { 

     UpdateProgressDelegate delegate = new UpdateProgressDelegate(DisplayResult); 
     myGrid.BeginInvoke(delegate, new object[] { rowIndex, message }); 

    } 

} 

내가 왼쪽하고있어이 문제

은 다음과 같습니다 : 양식이 폐쇄되면

  1. , 나는 (그에 의해 호출 된 LongProcess 기다려야 할 다음

    내 코드입니다 내 OperateGridMethodDelegate) 최대 행을 마친 후 취소 (같은 방법으로 내가 ButtonTwo 함께),하지만이 작동하도록 가져올 수 없습니다.

  2. 디버깅 할 때 이상한 동작을 발견하고이 버그가 맞는지 또는 처리가 완료 될 때 결과가 설정되지 않았는지 확실하지 않습니다. 대신 다음 행이 처리 된 다음 이전 행 결과가 표시됩니다. 세 번째 행이 완료되면 두 번째 행 결과가 표시됩니다. 그런 다음 마지막 두 행 결과는 기본적으로 동시에 표시됩니다.

정확하게 접근하고 있습니까? 당신이 당신이 할 수있는 진행하기 전에 끝날 때까지 기다려야하는 스레드에서 일부 작업을 시작했다면

+3

대리자의 BeginInvoke() 메서드를 사용하여 스레딩을 구현하지 마십시오. * bool *은 동기화 프리미티브가 아닙니다. 이 작업을 수행하는 더 좋은 방법이 있습니다.이 작업을 BackgroundWorker에 올바르게 처리하는 방법은 [this Q + A] (http://stackoverflow.com/a/1732361/17034)에서 다룹니다. –

답변

0

:

yourThread.Join(); 

이는 스레드가 종료 될 때까지 차단합니다.

yourThread.IsBackground = true; 

: 당신은 스레드가 자동으로 응용 프로그램이 종료되면 종료하려는 경우,

또는 당신의 Form_Closing 이벤트 같은 것을 사용할 수 있습니다, 당신은 스레드의 배경 속성을 설정해야합니다 이는 메인 (UI) 스레드의 백그라운드 스레드이므로 메인 스레드로 끝날 것임을 의미합니다.

편집 :

자신의 스레드를 사용 : 이제 완료 어딘가에 차단이 대기 할 경우

private Thread yourThread = new Thread(() = > LongProcess()); 
yourThread.IsBackground = true; 
yourThread.Start(); // This will begin your 'LongProcess' function. 

을, 당신은 내가 먼저 언급 무엇을 할 수 : 또한 yourThread.Join();

IsBackground = false을 설정하고 누군가 응용 프로그램을 닫으면 해당 스레드는 즉시 종료되지 않고 UI 창이 닫혀 있어도 완료 될 때까지 계속됩니다.

+0

yourThread는 무엇입니까? 이걸 어디서 구할 수 있니? 정확히 일치하지 않는 Im –

+0

답변에 더 추가했습니다.쓰레드를 제어하고 싶다면, 자신 만의'Thread' 객체를 사용해야합니다. – pay

+0

내 코드 대신이 말을하려고합니까? private void ButtonOne_Click (object sender, EventArgs e) { isCancelled = false; OperateGridMethodDelegate 대리자 = 새 OperateGridMethodDelegate (LongProcess); ' delegate.BeginInvoke (null, null); }이 작업을 수행해야합니까? 개인 무효 ButtonOne_Click (개체 발신자, EventArgs 전자) { isCancelled = false; 비공개 스레드 yourThread = new Thread (() => LongProcess()); yourThread.IsBackground = true; yourThread.Start(); } –