2013-07-15 3 views
0

Я хочу создать метод, который будет ждать, пока не будет загружен документ.Webrowser - ожидание загрузки документа

У меня есть что-то вроде этого:

WebBrowser webBrowser = new WebBrowser(); 
MyClient client = new MyClient(webBrowser); 
client.LogIn("test", "omg"); //block thread 
client.NotImplemented(); //i'm already logged; 

class MyClient 
{  
    bool Started; 
    WebBrowser webBrowser; 

    public MyClient(WebBrowser wb) 
    { 
     webBrowser = wb;  
     webBrowser.DocumentCompleted += (sender, e) => 
     { 
      if (e.Url == webBrowser.Url) 
      { 
       Started = false; //page loaded 
      } 
     }; 
    } 

    public void LogIn(string login, string password) 
    { 
     this.Navigate("mymagicsite.com"); 
    } 

    private void Navigate(string url) 
    { 
     webBrowser.Navigate(url); 
     Started = true; 

     while(Started) 
      Task.Delay(50); 
    } 
} 

И когда я буду вызов метода LogIn я хочу «блок» мой поток. Проблема в Task.Delay, она блокирует навигацию и ничего не происходит.

+0

Я не понимаю - что именно вы спрашиваете с приведенным выше кодом? Какая у вас проблема? –

+0

Проблема в том, что webBrowser.Navigate() не блокирует поток (я хочу что-то вроде webClient.DownloadString («www.google.pl») - он блокирует текущий поток). – Yozer

ответ

1

Вы можете использовать TaskCompletionSource отправить async -совместимый " уведомление "о каком-либо событии.

Как это:

class MyClient 
{  
    TaskCompletionSource<object> navigation; 
    WebBrowser webBrowser; 

    public MyClient(WebBrowser wb) 
    { 
    navigation = new TaskCompletionSource<object>(); 
    webBrowser = wb;  
    webBrowser.DocumentCompleted += (sender, e) => 
    { 
     if (e.Url == webBrowser.Url) 
     { 
     navigation.TrySetCompleted(null); 
     } 
    }; 
    } 

    public Task LogIn(string login, string password) 
    { 
    navigation = new TaskCompletionSource<object>(); 
    webBrowser.Navigate(url); 
    return navigation.Task; 
    } 
} 

который может быть использован как таковые:

WebBrowser webBrowser = new WebBrowser(); 
MyClient client = new MyClient(webBrowser); 
await client.LogIn("test", "omg"); 
+0

Спасибо, отлично работает! – Yozer

0

Вы должны покинуть поток пользовательского интерфейса происходит, как и отключить форму и включить один раз загрузка осуществляется

Использование

MyClient client = new MyClient(webBrowser, 
      () => { client.NotImplemented(); //i'm already logged; } 
     ); 
client.LogIn("test", "omg"); //block thread 

Implemation

class MyClient 
{  
    Form frm; 

    public MyClient(WebBrowser wb, MethodInvoker callback) 
    { 
     frm = (Form) wb.Parent; // assume WebBrowser is directly on the form 
     webBrowser = wb;  
     webBrowser.DocumentCompleted += (sender, e) => 
     { 
      frm.Invoke(new MethodInvoker(() => frm.Enabled = true)); 
      frm.Invoke(callback);  
     }; 
    } 

    private void Navigate(string url) 
    { 
     webBrowser.Navigate(url); 
     frm.Enabled = false; 
    } 
} 
+0

Это не работает. Я не знаю, почему, но событие DocumentCompleted даже не срабатывает ... – Yozer

+0

Если вы используете скрипач, вы видите, что naviagtion имеет место? Если вы удалите строку if (e.Url == ...), тогда она работает? – rene

+0

Я пробовал этот простой код: webBrowser.Navigate ("http://www.google.pl"); while (webBrowser.ReadyState! = WebBrowserReadyState.Complete) { Task.Delay (50); } Но ReadyState неинициализируется все время. Кажется, что Navigate работает над потоком пользовательского интерфейса, и когда я блокирую этот поток, навигация не запущена. – Yozer

Смежные вопросы