2011-02-17 3 views
5

나는 (이전의) SQL 서버에서 데이터를 검색하고 나가는 스레드가 있습니다.C# 스레드를 죽이는 방법?

데이터가 들어 오면 모달 대화 상자에 정보를 게시합니다.이 모든 처리가 진행되는 동안 &은 다른 작업을 수행해서는 안됩니다. 모달 대화 상자는 내가 뭔가를하고 있으며 동시에 다른 쿼리를 실행하지 못하게하는 것입니다.

SQL 서버를 호출 할 때 (드물게) 서버가 응답하지 않습니다 (유지 관리, LAN 회선이 끊어 지거나 PC가 네트워크에 연결되어 있지 않음). 쿼리를 수행하는 사람이 시간이 없습니다. 따라서 모달 대화 상자에는 취소 버튼이 있습니다.

스레드 개체 (System.Threading.Thread)의 스레드 수는 IsBackground=true입니다.

누군가가 취소를 클릭하면 나는 KillThread 방법으로 전화합니다.

참고 :이 & WM5가 BackgroundWorker에없는 몇 가지 윈도우 모바일 5 코드를 공유하기 때문에 내가이 클래스에서 BackgroundWorker 구성 요소를 사용할 수 없습니다.

void KillThread(Thread th) { 
    if (th != null) { 
    ManualResetEvent mre = new ManualResetEvent(false); 
    Thread thread1 = new Thread(
    () => 
     { 
     try { 
      if (th.IsAlive) { 
      //th.Stop(); 
      // 'System.Threading.Thread' does not contain a definition for 'Stop' 
      // and no extension method 'Stop' accepting a first argument of type 
      // 'System.Threading.Thread' could be found (are you missing a using 
      // directive or an assembly reference?) 
      th.Abort(); 
      } 
     } catch (Exception err) { 
      Console.WriteLine(err); 
     } finally { 
      mre.Set(); 
     } 
     } 
    ); 
    string text = "Thread Killer"; 
    thread1.IsBackground = true; 
    thread1.Name = text; 
    thread1.Start(); 
    bool worked = mre.WaitOne(1000); 
    if (!worked) { 
     Console.WriteLine(text + " Failed"); 
    } 
    th = null; 
    } 
} 

출력 창에 "스레드 킬러 실패"가 표시되지만 예외가 발생하지 않습니다.

스레드를 어떻게 중지해야합니까?

가장 관련 게시물은 내가 발견 한 곳이 아래 :

How to Kill Thread in C#?
How to kill a thread instantly in C#?

이 편집 : 보인다

이 방법에 약간의 혼동이 될 위에 나열된.

누군가가 취소 버튼을 클릭하면,이 루틴이 호출

첫째 : 내가 스레드를 죽일에 갈 때

void Cancel_Click(object sender, EventArgs e) { 
    KillThread(myThread); 
} 

다음, 차라리 중지 스레드가 영원히 기다릴 필요가 없습니다 것 . 동시에 스레드가 여전히 활성화되어 있으면 코드를 진행시키고 싶지 않습니다. 따라서 ManualResetEvent 개체를 사용합니다. 이 스레드를 중지하기 위해 전체 초 (1000ms)를 사용하지 않아야하지만, WaitOne 메서드가 시간 초과 될 때마다 발생합니다.

아직 아이디어를 듣고 있습니다.

답변

7

짧은 답변 : 그렇지 않습니다. 일반적으로 당신은 당신이 그만두기를 원하는 신호로 그것을합니다. SQL 쿼리를 실행하는 경우 비동기 적으로 (내 철자를 용인하십시오) 필요한 경우 취소하십시오. 그것은 정말로 별도의 스레드에서 긴 작업을 수행합니다. 당신은 SQL 서버를 호출하려면 어떻게 : Careful with that axe, part one: Should I specify a timeout?Careful with that axe, part two: What about exceptions?

편집 : 더 읽기

에릭 Lippert의의 문서를 참조하십시오? ADO, TDS, 표준/사용자 라이브러리 등 ...? 그 호출은 비동기로 만들어야합니다. 따라서 : StartOpeningConnection, OpeningComplete, StartQuery, QueryComplete 대기, CloseConnection 시작, CloseConnectionComplete 대기 등 스레드가 대기해야하는 대기 중. 깨어 난 후 부모 스레드 (UI 스레드)가 취소되었거나 시간 초과가 발생했는지 확인하고 스레드를 종료하고 sqlserver에 작업 완료 (연결 종료)를 알립니다.

... 편집 2

그것은 쉬운 일이 아닙니다, 그러나 거의 없다 : 귀하의 경우에, 당신은 asynchrone하기 위해 데이터베이스 코드를 변경 그것에게 별도의 과정을하고 있음을 죽일 수없는 경우 neccesary 경우 . 그러면 리소스 (연결 등)가 해제됩니다. 스레드의 경우에는 그렇지 않습니다. 그러나 추한 해킹입니다.

편집 3 : BeginExecuteReader/EndExecuteReader 패턴을 사용해야합니다. this article is a good reference: 데이터 액세스 코드를 다시 작성해야하지만 올바르게 수행하는 방법입니다.

+0

비동기 종료 요청으로 SQL 쿼리 신호를 보내거나 그 요청을 취소하는 방법을 이해할 수 없지만 지금 당신의 해당 2 연결을 읽고 있어요. 그들은 길기 때문에 거기에 대답이 있다면 나는 언젠가 그것을 가질 것입니다. – jp2code

+0

오케이, 기사를 읽었습니다. 내 문제는 SQL Server 2000에는 호출을 중단 할 수있는 방법이 없으므로 이전 서버가 버그라고 가정합니다 (Eric Lippert의 기사). – jp2code

+0

그럼, 어떻게해야합니까? 'Abort()'를 호출하고'ManualResetEvent'를 사용하여 GUI를 반환하거나 스레드를'null'으로 설정합니까? 플랜트에있는 모든 사람들이 합류 된 스레드가 종료되기를 영원히 기다리게하지 않을 것입니다. – jp2code

0

사용자가 취소 (스레드를 죽이지 않음)를 클릭하면 이벤트를 알려야합니다. 귀하의 예제에서 ManualResetEvent "mre"의 범위는 스레드 함수 외부에 있어야합니다.

+0

내 게시물을 편집 할 예정입니다. 나는 이것을 잘못 말한 것 같아. – jp2code

+0

여기 (MarcelDevG도 지적했듯이) 요점은 단지 스레드를 죽이는 것이 아니라는 것입니다. 스레드는 정상적으로 종료되고 자체적으로 정리되어야합니다. –

+0

그럴 생각입니다. 그러나 SQL Server 2000에 쿼리 작업을 중단하도록 지시 할 방법이 없습니다. 나는 단순히 스레드를 버릴 수 있다고 가정하고 (다음 쿼리가 수행 될 때 NULL로 설정 한 후 새 인스턴스를 생성 함) 스레드를 중지하는 방법을 알고 싶습니다. – jp2code

2

스레드 1000ms에 중단을 지정하면 충분하지 않다는 느낌이 들게됩니다. MSDN에서는 Thread.Join을 호출 할 것을 권장합니다. 중단되는 코드를 보는 것이 도움이 될 것입니다.

스레드

Thread.Abort

전혀 즉시 을 중단 보장, 또는하지 않습니다. 이 상황 은 abhand 절차의 일부분 인 으로 호출되는 finally 블록에서 무한대의 계산을 수행 할 때 발생할 수 있습니다. 따라서 중단을 무기한 지연합니다. 스레드가 중단 될 때까지 대기하려면 스레드는 스레드에서 Join 메서드를 호출 할 수 있지만 끝까지 보장 할 수는 없습니다.

+0

글쎄, 질의에 채워지는 커스텀 디자인의 오브젝트가 많이 있습니다. 쿼리는 6 개의 다른 데이터 테이블을 폴링합니다 (필자는 시스템을 설계하지 않았고, 소프트웨어를 작성했습니다). 각 테이블을 쿼리하기 전에 스레드가 중단되었는지 확인합니다. 인종 상황, 어쩌면, 그게 전부입니다. – jp2code

+0

스레드 가입은 나쁜 생각입니다.누군가가 취소를 클릭하고 스레드에 참여하라는 메시지가 표시되면 스레드가 종료되지 않고 GUI가 해당 단계에서 잠긴 경우가 있습니다. – jp2code

+0

@ jp2code - Thread.Join은 오버로드되어이 문제를 피할 수있는 시간 초과 매개 변수를 포함합니다. – ChaosPandion

1

KillThread 방법으로 무엇을 전달합니까? 취소하려는 UI 스레드에서 취소 버튼을 클릭합니다.

+0

버튼 클릭 방식은'KillThread (Thread th)'를 호출합니다. 나는 그것을 게시 할 필요성을 보지 못했다. – jp2code

+0

@ jp2code : 작업자 스레드에 대한 참조를 보유하고 있습니까? 그것이 제가 얻은 것입니다 :-) –

+0

오! 그렇습니다, 그것은 세계적입니다. – jp2code

관련 문제