2010-11-23 2 views
1

이벤트 StatusChanged & ProgressChanged를 통해 진행 상황을 보여주는 요청 데이터를 업로드하는 GetResponseStream() 클래스가있는 HttpHelper 클래스가 있다고 가정합니다.기능 비동기/비 차단을 만드는 방법에 대한 지침이 필요합니다.

public MemoryStream GetResponseStream() { 
    ... 
    Status = Statuses.Uploading; // this doesn't raise StatusChanged 
    // write to request stream 
    ... // as I write to stream, ProgressChanged doesn't get raised too 
    Status = Statuses.Downloading; // this too 
    // write to response stream 
    ... // same here 
    Status = Statuses.Idle; // this runs ok. Event triggered, UI updated 
} 

코드 @pastebin. GetRequestStream() on line 76. 사용하는 클래스가 아래처럼 호출해야하는 경우를 제외하고는 클래스 자체가 잘 작동합니다.

HttpHelper helper = new HttpHelper("http://localhost/uploadTest.php"); 
helper.AddFileHeader("test.txt", "test.txt", "text/plain", File.ReadAllBytes("./test.txt")); 
helper.StatusChanged += (s, evt) => 
{ 
    _dispatcher.Invoke(new Action(() => txtStatus.Text = helper.Status.ToString())); 

    if (helper.Status == HttpHelper.Statuses.Idle || helper.Status == HttpHelper.Statuses.Error) 
     _dispatcher.Invoke(new Action(() => progBar.IsIndeterminate = false)); 

    if (helper.Status == HttpHelper.Statuses.Error) 
     _dispatcher.Invoke(new Action(() => txtStatus.Text = helper.Error.Message)); 
}; 
helper.ProgressChanged += (s, evt) => 
{ 
    if (helper.Progress.HasValue) 
     _dispatcher.Invoke(new Action(() => progBar.Value = (double)helper.Progress)); 
    else 
     _dispatcher.Invoke(new Action(() => progBar.IsIndeterminate = true)); 
}; 
Task.Factory.StartNew(() => helper.GetResponseString()); 

helper.GetResponseString(); 

를 사용하여 클래스를 호출 한 경우 클래스 자체는 작동하지만 이벤트 제기 된 것 같지 않습니다. 나는 그것이 차단되는 UI 스레드와 관련이 있다고 생각한다. _dispatcher & Task 자료를 사용하지 않고 클래스를 쉽게 사용할 수 있도록 클래스를 다시 코딩하는 방법은 무엇입니까?

또한, 나는 이벤트/UI가 업데이트되지 않도록하는 원인을 확실히 알고 싶습니다. 코드가 동기식이라 할지라도 어쨌든 속성 변경/이벤트를 실행할 수 없으며 읽기/쓰기 afterall 이후에?

+0

PasteBin 구문 강조를 C#으로 설정해야합니다. http://pastebin.com/FeAPB6rU – SLaks

+0

@SLaks, 저에게 통보 해 주셔서 감사합니다. PHP yest를 사용하고 있었고 언어 변경을 잊어 버렸을 것입니다. –

답변

2

직접 손으로 직접 만드는 대신 BackgroundWorker을 사용해야합니다. ReportProgress을 사용하여 UI 스레드에 처리 상태를 전달하십시오.

+1

이 질문에 대한 좋은 제안 일지 모르지만, 왜냐하면 이것은 덜 좋을 수도있는 시나리오가 있기 때문입니다.이 제안의 문제점은 작업이 진행되는 동안 스레드를 소비하게 될 것이라는 것입니다. 클라이언트 측 코드에서 문제가 될 것 같지 않지만 문제는 서버 측 코드에서 일을 비동기 적으로 수행 할 수 없게 만듭니다. 네트워킹 클래스의 전체 비동기 사용은 스레드를 훨씬 더 단조롭게 사용할 수있게 해주어 때로는 서버 확장성에 도움이됩니다. (그러나 여기에 overengineering 될 것입니다.) –

+0

+1 이언 Ian. –

관련 문제