2014-09-28 3 views
0

아래 코드와 같이 webbrowser에서 탐색 한 후 html을 얻는 방법. 이 DLL 라이브러리는 다른 프로젝트에서 사용할 수 있으며 winforms가 아닙니다. navigate를 호출 한 후 기다리지 않습니다.webbrowser.navigate에 동 기적으로 액세스하는 방법

public List<Category> Categories; 
public WebBrowser Browser; 

public List<Category> ListAllCategories() 
{ 
    Browser.DocumentCompleted += ReadAllCategories; 
    Browser.Navigate(CoursesLink); 
    //want to wait here until categories are built in the ReadAllCategories method without wasting CPU cycles 
    return Categories; 
} 

void ReadAllCategories(object sender, WebBrowserDocumentCompletedEventArgs e) 
{ 
    WebBrowser browser = sender as WebBrowser; 
    switch (browser.ReadyState) 
    { 
     case WebBrowserReadyState.Complete: 
      if (browser.Document != null) 
      { 
       //buildingListofCategories 
      } 
      break; 
     case WebBrowserReadyState.Interactive: 
      break; 
     case WebBrowserReadyState.Loaded: 
      break; 
     case WebBrowserReadyState.Loading: 
      break; 
     case WebBrowserReadyState.Uninitialized: 
      break; 
     default: 
      break; 
    } 
    browser.DocumentCompleted -= ReadAllCategories; 
} 
+0

'async'를 사용하여 자신 만의'작업 '을 만들어야합니다. – SLaks

답변

0

여기에는 몇 가지 방법이 있습니다. (:을 테스트하지 경고) :

public List<Category> GetAllCategories(Uri CoursesLink) 
{ 
    List<Category> categories = new List<Category>(); 
    ManualResetEventSlim waitEvent; 
    using (WebBrowser browser = new WebBrowser()) 
    { 
     waitEvent = new ManualResetEventSlim(); 
     browser.DocumentCompleted += (s, e) => 
     { 
      switch (browser.ReadyState) 
      { 
       case WebBrowserReadyState.Complete: 
        // TODO: your processing, filling categories 
        waitEvent.Set(); 
        break; 
       // TODO: error processing 
      } 
     }; 
     browser.Navigate(CoursesLink); 
    } 
    waitEvent.Wait(); // TODO: timeout? 
    return categories; 
} 

다른 하나는 물론, 사용하는 작업이 비동기 적으로 완료 될 때까지 한 가지 방법은 단순히 스레드를 차단하는 동기화 기본을 사용하여 하나의 방법으로 비동기 작업을 캡슐화하는 것입니다 내장 Task 지원 (Schabse 언급 한 것과 유사) Task 객체의 본질적으로 비동기 작업을 모델링하고 단순히 Wait (경고 :을 테스트하지) : 호출 할 .NET에서

public Task<List<Category>> GetAllCategoriesAsync(Uri CoursesLink) 
{ 
    var tcs = new TaskCompletionSource<List<Category>>(); 
    List<Category> categories = new List<Category>(); 
    using (WebBrowser browser = new WebBrowser()) 
    { 
     browser.DocumentCompleted += (s, e) => 
     { 
      switch (browser.ReadyState) 
      { 
       case WebBrowserReadyState.Complete: 
        // TODO: your processing, filling categories 
        tcs.SetResult(categories); 
        break; 
        // TODO: error processing 
      } 
     }; 
     browser.Navigate(CoursesLink); 
    } 
    return tcs.Task; 
} 

//... 

public List<Category> ListAllCategories() 
{ 
    return GetAllCategoriesAsync(CoursesLink).Result; 
} 
,369을

Task 기반의 메서드를 사용하는 것이 좋습니다. 실제로 가지고있는 것은 비동기 작업이며 실제로 완료하려면 을 기다리는 것입니다. 완료하려면을 기다리는 것이 좋습니다. 또한 UI에서 비동기 적으로 사용할 수 있습니다.

var categories = await GetAllCategoriesAsync(CoursesLink); 
+0

메소드가 작동하려면 정적으로 선언해야합니까? –

+0

아니, 그게 내가 어떻게 된 일인지. 나는 그것을 반영하기 위해 답을 편집 할 것이다. –

+0

ListAllCategories() 메서드는 인터페이스이며 [OperationContract] 특성으로 표시되어 있습니다. 이것도 똑같습니까? –

관련 문제