2011-08-17 3 views
4

시나리오 : 우리는 DataAdapter (데이터 테이블)에 첨부 된 DataGridView를 가지고 있으며, (adapter.fill (query, datatable))를 사용하여 데이터 테이블에 데이터를로드합니다. beginInvoke) 일단 데이터가로드되면 해당 데이터 테이블을 datagridview (주 스레드)에 연결합니다.DataAdapter.Fill 취소()

fill()이 아직 실행 중인지 확인하고 취소 할 수있는 방법이 있습니까?

실제 시나리오 : 사용자가 사용자 이름을 클릭하면 해당 데이터가 DataGrid에로드됩니다. 가끔은 사용자가 참을성이 없어서 다른 사용자를 클릭합니다. 여기에서 이전 채우기를 취소하고 새 채우기를 시작합니다.

업데이트 : 두 명의 DataApdater (및 두 개의 DataTable)를 유지하고 하나의 datatable을 datagridview에 연결하고 데이터를 다른 데이터 테이블에 비동기 적으로로드하기 시작합니다. 데이터가로드되면 우리는 방금 채운 DataTable에 DataGridView를 바인딩합니다. 이전 데이터 테이블을 비동기 적으로로드하기 시작합니다.이 방법으로 UI는 항상 현재 데이터를 가져옵니다 (사용자가 UI를 새로 고치거나 정지 할 때 대기하지 않고).

+2

"C# ADO.net"과 같은 것을 제목에 넣지 마십시오. 그것이 [SO]에 대한 태그입니다. –

+0

AsyncMethodCaller를 IAsyncResult와 함께 사용하고 있습니까? –

+0

@James, 나는 일반 Delegate를 사용하고 beginInvoke를 호출한다. 결국 데이터 테이블을 채 웁니다. 콜백 메서드에서 나는 그 데이터를 DataGrid에 바인딩합니다. – karephul

답변

0

안전하게 아무 시설도 취소 DataAdapter.Fill().

이 문제를 해결하려면 이러한 원치 않는 채우기가 무시되어 UI에 반영되지 않도록하는 메커니즘을 구현하는 것이 좋습니다. 비동기 작업을 시작할 때 카운터를 증가시키고 해당 상태를 asyn 작업에 전달하는 것이 좋습니다. 그런 다음 비동기 작업이 끝나면 현재 카운터에 대한 카운터 값을 확인할 수 있습니다. 카운터가 동일하지 않으면 UI를 업데이트하지 마십시오.

사용자가 빠르게 사용자를 클릭하고 많은 요청이 삭제되는 패턴을 발견하면 사용자가 최소 시간 동안 선택 항목에 머무르는 경우에만 데이터를 검색하는 타이머 메커니즘을 구현하십시오.

+0

실제 문제는 다른 하나가 실행될 때 differnt 쿼리로 adapter.fill (query, datatable)을 다시 호출하려고하면 "IllegalOperationException"이 throw된다는 것입니다. DataAdapter는 클라이언트가 적절한 조치를 취해야한다고 판단하여 상태를 확인하는 API를 공개해야한다고 생각합니다. – karephul

+0

저는 현재 같은 일을하고 있습니다. 플래그를 직접 (실행 중) 유지하고 그에 기반하여 요청을 처리합니다. 그러나 채우기가 오랜 시간이 걸리는 경우, 필자는 어쨌든 필 요없는 채우기를 기다리고 있습니다. – karephul

+0

@karephul 각 호출에 대해 새 DataAdapter를 사용해야합니다. 그러면 무시 된 채우기를 기다릴 필요가 없습니다. –

0

빠른 검색을 수행하여 다음을 찾았습니다. cancel a DataAdapter.Fill 코드 작성자가 예외 처리를 피할 방법이없는 것 같습니다.

+0

그 링크도 보았습니다. – karephul

1

어댑터 생성자에 SqlCommand를 제공하고 여기에 Cancel 메서드를 호출 할 수 있습니다. 원시 템플릿이 있습니다.

class Model 
{ 
    private SqlCommand loadUserCommand; 
    private DataTable userData; 

    public void LoadUser(string userId) 
    { 
     loadUserCommand = GetUserLoadCommandForUserID(userId); 
     userData = new DataTable("userData"); 
     using (var adapter = new SqlDataAdapter(loadUserCommand)) 
     { 
      adapter.Fill(userData); 
     } 
    } 

    public void AbortLoadUser() 
    { 
     if (loadUserCommand!= null) 
      loadUserCommand.Cancel(); 
    } 


    private SqlCommand GetUserLoadCommandForUserID(string userId) 
    { 
     var connection = new SqlConnection("..."); 
     var command = connection.CreateCommand(); 
     ... 
    } 
} 
+0

Nothing calls AbortLoadUser는 템플릿입니다. 그걸 부름받은 것을 어떻게 상상합니까? –

+0

LoadUser 및 AbortLoadUser는 Model 클래스의 공용 메서드이며 UI에서 호출 할 수 있습니다 (예 : 단추 클릭 이벤트 처리기). – igorushi