2016-04-28 36 views
1

完全なstring result = browser.Browse(url)メソッドを作成するために、CefSharpをデモンストレーションするための簡単なクラスライブラリを作成しました。そのためのコードは次のとおりです。CefSharpを使用したタスクの完了時に非同期コンソールプログラムがハングアップする

public class CefSharpHeadlessBrowser 
{ 
    public CefSharpHeadlessBrowser() 
    { 
     Cef.Initialize(new CefSettings { CachePath = "cache" }, false, true); 
    } 

    public string Browse(string url) 
    { 
     Task<string> result; 

     var browserSettings = new BrowserSettings { WindowlessFrameRate = 1 }; 

     using (var browser = new ChromiumWebBrowser(url, browserSettings)) 
     { 
      browser.WaitForBrowserToInitialize(); 

      browser.LoadPageAsync(); 

      // Wait awhile for Javascript to finish executing. 
      Thread.Sleep(2000); 

      result = browser.GetSourceAsync(); 
      Thread.Sleep(100); 
     } 
     return result.Result; 
    } 
} 

public static class CefExtensions 
{ 
    public static void WaitForBrowserToInitialize(this ChromiumWebBrowser browser) 
    { 
     while (!browser.IsBrowserInitialized) 
     { 
      Task.Delay(100); 
     } 
    } 

    public static Task LoadPageAsync(this IWebBrowser browser) 
    { 
     var tcs = new TaskCompletionSource<bool>(); 

     EventHandler<LoadingStateChangedEventArgs> handler = null; 
     handler = (sender, args) => 
     { 
      if (!args.IsLoading) 
      { 
       browser.LoadingStateChanged -= handler; 
       tcs.TrySetResult(true); 
      } 
     }; 

     browser.LoadingStateChanged += handler; 
     return tcs.Task; 
    } 
} 

これはCefSharpHeadlessBrowserプロジェクト参照別のコンソールプロジェクトでは、テストハーネスである:これは実際に動作

class Program 
{ 
    static void Main(string[] args) 
    { 
     const string searchUrl = "https://www.google.com"; 

     var browser = new CefSharpHeadlessBrowser(); 

     var result = browser.Browse(searchUrl); 
     Console.Write(result); 
    } 
} 

を。 HTMLページソースを適切に取得し、コンソールウィンドウに表示する必要があります。しかしここに問題があります。ページソースを表示した後にコンソールプログラムがハングします。すぐに終了する必要があります。これは、私が非同期操作に何か間違っていて、デッドロックを引き起こしていることを意味するはずです。

何が問題になりますか?

+0

あなたは 'Main'メソッドが返っても、アプリケーションは開いたままであると言っていますか?別のフォアグラウンドスレッドが実行されていますか? –

+0

@ YacoubMassad:それは良い手掛かりです。私はそれを解決したと思う。すぐに答える。 –

+0

既にCef.Shutdown()への欠落した呼び出しを投稿しているので。より完全な例はhttps://github.com/cefsharp/CefSharp/blob/cefsharp/49/CefSharp.OffScreen.Example/Program.csです。 – amaitland

答えて

1

CefSharpにはシャットダウンコマンドがあります。その後、

public void Shutdown() 
    { 
     Cef.Shutdown(); 
    } 

とTOテストハーネスを変更する:

class Program 
{ 
    static void Main(string[] args) 
    { 
     const string searchUrl = "https://www.google.com"; 

     var browser = new CefSharpHeadlessBrowser(); 

     var result = browser.Browse(searchUrl); 
     Console.WriteLine(result); 
     browser.Shutdown(); // Added 
    } 
} 

これは間違いなく実行されている任意の残りのスレッドを解放し、私はCefSharpHeadlessBrowserクラスに次のメソッドを追加することで問題を解決することができました。

おそらくクラスIDisposableを作成し、usingステートメントで呼び出しコードをラップします。

関連する問題