2009-08-25 3 views
2

두 번째 스레드에서 System.IO.Stream (또는 래퍼 또는 판독기)을 안전하게 닫을 수 있습니까?다른 스레드에서 stream.Close를 호출 할 수 있습니까?

네트워크에서 읽는 시간이 new System.IO.StreamReader(inputStream, Encoding.ASCII);이며 다른 스레드에서 해당 값을 닫는 것이 좋습니다.

이것이 좋은 생각이 아니라면 읽기 호출에서 스레드 차단을 강제로 반환하는 또 다른 방법은 무엇입니까?

답변

2

아니요 맹목적으로 별도의 스레드에서 Close 메서드를 호출하는 것은 안전하지 않습니다. 스트림 클래스는 스레드 안전으로 나열되지 않고 원래 스레드가을 사용하는 동안 다른 스레드 에서 닫기를 호출하면 정의되지 않은 동작이 발생합니다.

1

예, inputStream이 소켓에서 읽는 경우 소켓 연결을 닫을 다른 스레드에서 처리 할 수 ​​있습니다. 읽기 차단 호출은 예외를 throw합니다.

1

이 상황에서 단정 정리하는 일반적인 방법은 다음과 같습니다

  1. 가 차단 읽기 일부 데이터를 얻을 수 있도록 소켓에 일부 데이터 쓰기 완료 (예 : IsDone = true)
  2. 를 나타내는 값을 설정
  3. 소켓에서 읽는 스레드에서 읽기 데이터를 처리하기 전에 IsDone이 참인지 확인하십시오. IsDone이 true이면 데이터를 무시하고 스트림을 닫습니다.

이렇게하면 Jared가 참조하는 문제를 피할 수 있습니다.

+0

드문 경우이지만 소켓 연결의 양쪽 끝을 제어하는 ​​경우 반드시 2 단계 만 수행하면됩니다. –

+0

@Mark : 맞아요, 음, 실제로 이것은 여러분이 듣고있는 것과 같은면에서 스트림에 글을 쓸 수 있다고 가정합니다 ... 저는 그 중 하나에서 점심을 먹을 수도 있습니다 ... –

0

예, 다른 스레드에서 스트림을 닫지 만 문제가 발생하는 경우에는 문제가되지 않습니다. 다른 스레드가 해당 스트림을 사용하고 있다면 예외가 발생합니다. 올바른 작업은 이벤트를 처리하는 스레드가 종료해야 하는지를 확인할 수있는 이벤트 또는 대기 핸들을 갖는 것입니다. 의사 코드는 다음과 같습니다. 스레드 1 읽기 작업을 보류하고 읽을 데이터가 있는지 확인하십시오.
ther의 데이터가 있으면 일부 데이터를 읽으십시오. 그렇지 않은 경우 계속 대기 핸들을 확인하십시오. 설정되어 있으면 닫고 끝내십시오. 조금 더 읽으십시오. 루프

스레드 2.연결을 끊을 네트워크를 트리거해야한다면, 무엇이든 기다리는 신호를 보내십시오.

차단 작업중인 경우 예외가 발생합니다. 차단 소켓을 사용하지 않는 것이 좋습니다. 이유가 없습니다. 우리는 실제로 System.Net의 내부에서 모든 작업을 비동기 적으로 수행하며, 동기화 코드 경로는 비동기 코드 경로를 트리거 한 다음 완료 될 때까지 차단합니다.

+0

Jeff : 보는 것이 재미있을 것입니다. 이것의 코드 예제. leeeroy는 StreamReader를 사용하고 있습니다. 비동기 메소드가 없습니다. 즉, 네트워크 스트림에서 직접 읽은 다음 읽은 값을 텍스트 인코더로 "펌핑"해야합니까? – JMarsch

+0

StreamReader.Read가 차단되지 않으므로 비동기 메서드가 필요하지 않습니다. 더 이상 데이터가 없으면 -1을 반환합니다.당신이 할 일은 다음과 같습니다 : while (someCondition) { if (handle.WaitOne (1)) {// 스트림을 처리 할 시간 stream.Close(); stream.Dispose(); 다른 글 } 을 비 차단 myStreamDisposalCompleteHandle.Set()는 한다} else {// 스트림 데이터 stream.Read =()를 사용하여 아직 유효 //이된다 (appShouldCloseStreams) { 경우의 foreach (HandlesThatStreamsHave의 streamShouldCloseHandle 핸들) handle.Set(); WaitHandle.WaitAll (arayOfAllStreamDisposeCompleteHandles); App.Exit(); –

+0

위 서식에 죄송합니다. 이 코드에서 진행되는 작업은 스트림을 처리하는 각 스레드가 두 개의 핸들을 가지고 있다는 것입니다. 하나는 닫아야하는지 주기적으로 검사하고 하나는 스트림을 닫았 음을 알리는 데 사용할 수있는 핸들입니다. 주 스레드는 모든 스트림 스레드가 가지고있는 모든 핸들을 참조합니다. 끝날 때가되었음을 알릴 준비가되면 다른 모든 스레드에 신호를 보내고 신호가 끝날 때까지 기다립니다. 핸들에 ManualResetEvent 또는 AutoResetEvent 클래스를 사용하면 WaitHandle은 기본 클래스이지만 Set 메서드는 없습니다. –

관련 문제