使用CefSharp异步控制台程序在任务完成时挂起 [英] Asynchronous console program hangs on completion of task using CefSharp

查看:451
本文介绍了使用CefSharp异步控制台程序在任务完成时挂起的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在创建完美的 string result = browser.Browse(url)方法的过程中,我创建了一个简单的类库来演示CefSharp。的代码是:

In my quest to create the perfect string result = browser.Browse(url) method, I have created a simple class library to demonstrate CefSharp. The code for that is:

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项目:

This is the test harness, in a separate console project that references the CefSharpHeadlessBrowser project:

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页面源代码,并按需要在控制台窗口中显示它。但这是问题所在:控制台程序在显示页面源后挂起。它应立即退出。

This actually works; it gets the HTML page source properly and displays it in the console window, just as it should. But here's the problem: the console program hangs after displaying the page source. It should exit immediately. Which must mean that I'm doing something wrong with the asynchronous operations and causing a deadlock.

可能是什么问题?

推荐答案

CefSharp具有关闭命令;通过将以下方法添加到 CefSharpHeadlessBrowser 类中,我能够解决该问题:

CefSharp has a Shutdown command; I was able to solve the problem by adding the following method to the CefSharpHeadlessBrowser class:

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

然后将测试线束更改为:

And then changing the Test Harness 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 
    }
}

这无疑会释放所有剩余的线程正在运行。

This undoubtedly frees up any remaining threads that are running.

我可能会让类 IDisposable 并将调用代码包装在<$ c $中c>使用语句。

I'll probably make the class IDisposable and wrap the calling code in a using statement.

这篇关于使用CefSharp异步控制台程序在任务完成时挂起的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆