C# 在阻止UI线程时加载带有WebBrowser控件的html

C# 在阻止UI线程时加载带有WebBrowser控件的html,c#,winforms,async-await,webbrowser-control,wait,C#,Winforms,Async Await,Webbrowser Control,Wait,我有一个.NET4.5WinForms应用程序,它包含存储在数据库中的html。将向用户显示页面列表。当他们点击一行时,页面被加载到WebBrowser中。我希望加载页面的过程与主UI线程同步(注意,在加载页面之前,我不希望用户能够执行任何其他操作)。加载html的代码是: public class DocLoader { private readonly WebBrowser browser; readonly TaskCompletionSource<object>

我有一个.NET4.5WinForms应用程序,它包含存储在数据库中的html。将向用户显示页面列表。当他们点击一行时,页面被加载到WebBrowser中。我希望加载页面的过程与主UI线程同步(注意,在加载页面之前,我不希望用户能够执行任何其他操作)。加载html的代码是:

public class DocLoader
{
    private readonly WebBrowser browser;
    readonly TaskCompletionSource<object> loadedTCS = new TaskCompletionSource<object>();

    public DocLoader(WebBrowser browser)
    {
        this.browser = browser;
    }

    private void LoadedComplete(object sender, WebBrowserDocumentCompletedEventArgs e)
    {
        Debug.WriteLine("doc completed");
        loadedTCS.TrySetResult(null);
        browser.DocumentCompleted -= LoadedComplete;
    }

    public Task LoadDoc(string html)
    {
        browser.DocumentCompleted += LoadedComplete;
        browser.DocumentText = html;
        return loadedTCS.Task;
    }
}
将导致消息循环能够处理消息。这是不可取的。例如,用户可以在上一个文档完成加载之前单击列表中的另一个文档

按如下方式调用代码:

await new DocLoader(webBrowser1).LoadDoc(html);
new DocLoader(webBrowser1).LoadDoc(html).Wait();
可能是因为DocumentCompleted事件不会在消息循环运行的情况下触发而导致UI冻结和文档从未加载


是否仍有方法完成此任务并使进程与UI线程保持同步?

Web浏览器需要其父线程泵送消息才能正常运行。在您的情况下,它的父线程是主UI线程,因此不能使用
Wait
阻止它。一种可能是禁用整个UI,如
浏览器。DocumentText
异步加载相当快:

Cursor.Current=Cursors.WaitCursor;
mainFrom.Enabled=false;
尝试
{
等待新的文档加载器(webBrowser1).LoadDoc(html);
}
最后
{
mainFrom.Enabled=true;
Cursor.Current=Cursors.Default;
}
然而,这对用户来说是非常不友好的。正确的方法是在
WebBrowser
异步加载场景中支持取消。如果用户单击另一行(而上一行更新仍处于挂起状态),则需要取消挂起的操作,然后启动新的操作