Xilium CefGlue - Как синхронно получить исходный код HTML?

Я хочу получить исходный код веб-страницы в CEF3/Xilium CefGlue из потока без пользовательского интерфейса (закадровый браузер)

я делаю это

internal class TestCefLoadHandler : CefLoadHandler
{
    protected override void OnLoadStart(CefBrowser browser, CefFrame frame)
    {
        // A single CefBrowser instance can handle multiple requests for a single URL if there are frames (i.e. <FRAME>, <IFRAME>).
        if (frame.IsMain)
        {
            Console.WriteLine("START: {0}", browser.GetMainFrame().Url);
        }
    }

    protected override void OnLoadEnd(CefBrowser browser, CefFrame frame, int httpStatusCode)
    {
        if (frame.IsMain)
        {
            MyCefStringVisitor mcsv = new MyCefStringVisitor();
            frame.GetSource(mcsv);

            Console.WriteLine("END: {0}, {1}", browser.GetMainFrame().Url, httpStatusCode);
        }
    }
}

class MyCefStringVisitor : CefStringVisitor
{
    private string html;

    protected override void Visit(string value)
    {
        html = value;
    }
    public string Html
    {
        get { return html; }
        set { html = value; }
    }
}

But the call to the

GetSource(...)
is asynchronous, so I need to wait for the call to occur before trying to do anything with result.

Как я могу дождаться вызова?


person LeMoussel    schedule 26.03.2015    source источник
comment
GetSource(), это пустой метод, а не задача. Я не могу выполнить await GetSource(...)   -  person LeMoussel    schedule 26.03.2015


Ответы (1)


Согласно совету Алекса Мейтленда, который сказал мне, что я могу адаптировать реализацию CefSharp (https://github.com/cefsharp/CefSharp/blob/master/CefSharp/TaskStringVisitor.cs), чтобы сделать что-то подобное.

Я делаю это :

    protected override async void OnLoadEnd(CefBrowser browser, CefFrame frame, int httpStatusCode)
    {
        if (frame.IsMain)
        {
            // MAIN CALL TAKES PLACE HERE
            string HTMLsource = await browser.GetSourceAsync();
            Console.WriteLine("END: {0}, {1}", browser.GetMainFrame().Url, httpStatusCode);
        }
    }


public class TaskStringVisitor : CefStringVisitor
{
    private readonly TaskCompletionSource<string> taskCompletionSource;

    public TaskStringVisitor()
    {
        taskCompletionSource = new TaskCompletionSource<string>();
    }

    protected override void Visit(string value)
    {
        taskCompletionSource.SetResult(value);
    }

    public Task<string> Task
    {
        get { return taskCompletionSource.Task; }
    }
}

public static class CEFExtensions
{
    public static Task<string> GetSourceAsync(this CefBrowser browser)
    {
        TaskStringVisitor taskStringVisitor = new TaskStringVisitor();
        browser.GetMainFrame().GetSource(taskStringVisitor);
        return taskStringVisitor.Task;
    }
}  
person LeMoussel    schedule 27.03.2015
comment
Что вы делаете с HTMLSource? Есть ли способ вырваться из этого метода обратного вызова, чтобы вы могли его использовать? Может быть, назначить его публичной собственностью? - person Robert Harvey; 27.04.2016