2011-10-20 4 views
0

사용자 지정 컬렉션 (스레드로부터 안전한 ObservableQueue)이 있습니다. 컬렉션 클래스 내에 비즈니스 로직을 구현했습니다. 즉, 항목을 하나씩 dequeue하여 외부에 노출합니다. 이것은 잘 작동합니다. 컬렉션이 초기화 된 스레드를 차단하지 못하도록 OnservableQueue는 해당 작업을 수행 할 스레드를 구현합니다. 이제는 발생할 수있는 함정에 대해 확신 할 수 없습니다.컬렉션에 포함 된 스레드 만들기 및 종료

생성자의 스레드를 초기화하는 것 (시작하지 말고 초기화 만하는 것)입니까? 스레드를 종료하는 것이 좋지 않더라도 최선의 방법은 무엇입니까? 참고, 스레드를 종료하는 방법을 알 필요가 없다, 그 일을 잘하고있다, 나는 오히려 일회용 패턴을 사용하거나 스레드를 종료하기 위해 호출해야하는 메서드를 만드는 일을 잘못 뭔가 날씨에 관심이 있습니다. IDisposable을 구현하는 경우 수집/대기열과 관련하여 계정을 가져야하는 항목이 있습니까?

편집 : 스레드가 실제로에만 제대로 다시 initilised하는 인큐 방법에서 발생되는 NullReferenceException을 방지하기 위해-초기화 사전된다 (인큐 방법은 큐 해제 스레드가 이미하고있는 경우 실행 날씨를 확인하도록되어 새로운 것을 시작하지 마라). 모든 항목이 대기열에서 제외되고 스레드가 작업을 완료 할 때마다 대기열이 비어 있고 새 항목이 추가 될 때마다 대기열을 처리하기 위해 새 스레드가 시작됩니다.

if (!_dequeuingThread.IsAlive) 
{ 
    // start the dequeuing thread 
    _dequeuingThread = new Thread(new ThreadStart(StartDequeuing)); 
    _dequeuingThread.Name = "DeQueueThread"; 
    _dequeuingThread.Start(); 
} 

if 문에는 초기화 된 스레드가 필요합니다. 이를 달성 할 수있는 다른 방법이 있지만, 스레드를 미리 초기화하는 것이 가장 덜 불편한 것처럼 보였습니다. 날씨를 확인한 후에 스레드가 살아 있다는 것을 알 수 있습니다. 스레드가 사전 초기화되어 있으면 안되며 다시 제대로 초기화됩니다.

답변

0

생성자에서 초기화하는 데는 아무런 문제가 없지만 작업자 스레드와 다른 스레드에서 초기화된다는 점에 유의하십시오.

정지에 관해서는 일반적으로 작업자가 계속 실행되도록 확인하는 휘발성 부울 플래그가 있습니다. 작업자 쓰레드가 전혀 잠자기했다면, 잠자기가 아닌 이벤트를 기다려야하므로, 멈출 때 즉시 깨울 수 있습니다.

+0

작업자 스레드가 대기열에서 항목을 반복하여 순환하는 좁은 루프에서 실행 중입니다. 그 루프에서 휘발성 bool의 진실 값을 확인합니다. 그리고 루프를 반복하거나 살아 있지 않습니다. 그럼 실제로 깃발을 어디에 놓았습니까? 메서드 ('StopDequeuing()') 또는'IDisposable'을 구현합니까? –

+0

개인적으로 모두. 플래그를 설정하고 작업자 스레드가 종료 될 때까지 기다리는 StopDequeuing() 함수가 있고 StopDequeuing()을 호출 한 Dispose() 구현이 있습니다. – GazTheDestroyer

0

소비자가 생성자를 호출하여이 컬렉션 객체를 초기화하고 객체가 초기화 된 것으로 (생성자가 수행해야하는 것) 생각할 수있는 문제가있는 것처럼 보입니다. 생성자가 생성 한 별도의 스레드에서 초기화가 발생합니다. 따라서 기본적으로 소비자가 생성자를 사용하여 개체를 만든 후 initialize 메서드를 호출 한 다음 initialize 메서드에 콜백을 전달하거나이 메서드를 호출하기 위해이 컬렉션을 초기화하는 데이 일종의 "Asynchronous API on this object"를 구현해야합니다. 수집 객체의 이벤트에 등록함으로써 소비자는 초기화가 완료되었음을 알게됩니다.

+0

사실 스레드는 생성자에서 초기화되므로 나중에 Thread.IsAlive를 호출하면 NullReferenceException이 발생하지 않습니다. 실제 스레드가 _started_되기 전에 올바르게 초기화 될 것입니다. 이전의 dequeing 스레드가 작업을 끝냈을 때 (그리고 더 이상 살아 있지 않은 경우) 필요합니다.그 외에도'INotifyCollectionChanged' 인터페이스와'Dispatcher'를 구현 한 스레드 세이프 ObservableQueue와 달리, 그것은 초기화되고 OK로 완벽하게 업데이트됩니다 :) 스레드가 실제로 초기화되는 방법에 대해서는 위의 편집을 참조하십시오. –