문제

어 클래스 이름 BackgroundWorker 는 스레드는 지속적으로 실행할 수 있습니다.이 스레드 해제,인스턴스 라는 변수 stop 를 요구할 true.

을 확인하는 스레드 해제할 때 클래스가 완료 사용되는,나는 추가 IDisposable 고 종료자를 호출하는 Dispose().정 stop = true 가 실제로 원인이 쓰레드를 종료,이 sippet 정확합니까?그것은 잘 invoke Dispose 에서 종료자,right?

종료자는 항상 전화 Dispose 는 경우 objectIDisposable, 죠?

/// <summary>
/// Force the background thread to exit.
/// </summary>
public void Dispose()
{
    lock (this.locker)
    {
        this.stop = true;
    }
}

~BackgroundWorker()
{
    this.Dispose();
}
도움이 되었습니까?

해결책

결승전제를 잠그는 것은 다소 "무서운"것이지만 피할 것입니다. 교착 상태를 얻는다면 ... 나는 무슨 일이 일어날 지 100% 확신하지는 않지만 좋지 않을 것입니다. 그러나 안전하다면 이것은 문제가되지 않아야합니다. 주로. 쓰레기 수거의 내부는 고통스럽고 나는 당신이 그들을 볼 필요가 없기를 바랍니다.)

Marc Gravell이 지적했듯이, 휘발성 부울은 자물쇠를 제거 할 수있게 하여이 문제를 완화시킬 것입니다. 가능하면이 변경 사항을 구현하십시오.

Nedruod의 코드는 IF (처분) 점검 내부에 할당을 넣습니다. 이는 완전히 잘못된 것입니다. 스레드는 관리되지 않는 리소스이며 명시 적으로 처분하지 않더라도 중지해야합니다. 당신의 코드는 괜찮습니다. 나는 당신이 해당 코드 스 니펫에 주어진 조언을 받아서는 안된다고 지적하고 있습니다.

예, idisposable 패턴을 구현하는 경우 거의 항상 Finalizer에서 Dispose ()을 호출해야합니다. 완전한 idisposable 패턴은 당신이 가진 것보다 약간 더 크지 만 항상 필요하지는 않습니다. 단지 두 가지 추가 가능성을 제공합니다.

  1. Dispose ()가 호출되었는지 또는 최종화기가 실행되는지 여부를 감지합니다 (파이널 라이저의 관리 자원을 만질 수 없습니다.
  2. 서브 클래스가 dispose () 메소드를 무시할 수 있도록합니다.

다른 팁

우선, a 심한 경고. 당신과 같은 파이널 라이저를 사용하지 마십시오. 파이널 라이저 내에서 잠금을 취하면 매우 나쁜 효과를 위해 자신을 설정하고 있습니다. 짧은 이야기는 그것을하지 않는 것입니다. 이제 원래 질문에.

public void Dispose()
{
    Dispose(true);
    GC.SuppressFinalize(this);
}

/// <summary>
/// Force the background thread to exit.
/// </summary>
protected virtual void Dispose(bool disposing)
{
    if (disposing)
    {
        lock (this.locker)
        {
            this.stop = true;
        }
    }
}

~BackgroundWorker()
{
    Dispose(false);
}

최종화기가 전혀없는 유일한 이유는 하위 클래스가 확장 및 릴리스를 허용하는 것입니다. 관리되지 않는 자원. 서브 클래스가 없으면 클래스를 밀봉하고 최종화기를 완전히 떨어 뜨립니다.

이익이 없어도, 이것은 정규를 사용할 수없는 이유입니다. 배경 노동자, 어느 쪽이 취소를 완전히 지원 하는가?

잠금 장치 - 휘발성 부울 필드는 덜 번거 롭을 수 있습니다.

그러나이 경우 파이널 라이저는 특히 "if (disposing)"을 감안할 때 흥미로운 일을하지 않습니다. 즉, dispose () 중에 흥미로운 코드 만 실행됩니다. 개인적으로 나는 단지 idisposable을 고수하고 결승선을 제공하지 않으려는 유혹을 받았습니다. dispose ()로 청소해야합니다.

은"stop"인스턴스의 변수에 속?하지 않을 경우,거기에 특정 시점에 그것을 설정하는 동안에 종료자가 아무것도는 개체를 참조하는 이상,그래서 아무것도를 쿼리할 수 있는 회원에게 있습니다.

는 경우에 당신은 실제로 발표한 자원,그는 처분()및 종료자 수 같은 작업(첫 번째는지 여부를 테스트하고 작품은 여전히 할 필요)좋은 패턴이다.

전체 일회용 패턴이 필요하지만 스톱은 스레드가 액세스 할 수있는 것이어야합니다. 배치중인 클래스의 회원 변수 인 경우, 처분 된 클래스를 참조 할 수 없기 때문에 좋지 않습니다. 스레드가 소유 한 이벤트를 고려하고 대신 폐기 할 때 신호를 보내십시오.

Finalizer를 구현하는 객체는 플래그에 대한 참조가 필요합니다. 다른 대상에서-스레드가 볼 수있는 것; 스레드가 있어야합니다 ~ 아니다 최종화기를 구현하는 물체를 직접 또는 간접적으로 강력하게 참조하십시오. Finalizer는 비교 체인지와 같은 것을 사용하여 플래그를 설정해야하며 스레드는 비슷한 수단을 사용하여 테스트해야합니다. 한 객체의 최종화기가 다른 객체에 액세스하는 경우 다른 객체가 마무리되었을 수 있지만 여전히 존재합니다. 결승전제가 다른 개체를 참조하는 것은 결승에 의해 방해받지 않는 방식으로 다른 객체를 참조하는 것은 괜찮습니다. 당신이하는 일이 깃발을 설정하는 것만이라면 괜찮습니다.

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top