如何等待方法完成然后执行新操作?

时间:2020-01-05 00:25:25

标签: c# asynchronous asp.net-mvc-5 async-await

我正在设置我的体系结构以使用Cef.Offscreen。为了简化工作,我划分了一些部分。但是我遇到了一个问题,即控制器正在加载finshes并在一切都能够加载之前提供视图。

这是我的结构-> 控制器

public ActionResult InitBrowser()
    {

        ICefSharpRenderer renderer = RendererSingelton.GetInstance();
        //Try to render something in default appdomain
        renderer.LoginToTradingView(null, null);

        ViewBag.SiteTitle = BrowserActions.RunScriptInNamedBrowser("loginbrowser", @"(function() {return document.title;} )();");

        ViewBag.ImagesixtyfourUrl = BrowserActions.TakeScreenshot("loginbrowser");

        //this is returned to fast, we have to wait for all

        return View(); 
    }

我有这个班可以做一些基本的动作,并在需要时进行初始化。

public class CefSharpRenderer : MarshalByRefObject, ICefSharpRenderer
{
    private ChromiumWebBrowser _browser;
    private TaskCompletionSource<JavascriptResponse> _taskCompletionSource;
    private string _name;

    public void LoginToTradingView(string url, string browserName)
    {
        CheckIfCefIsInitialized();
        BrowserFactory.GetBrowserInstance(@"https://se.tradingview.com/", "loginbrowser");

    }


   public void CreateBrowserAndGoToUrl(string url, string browserName)
   {
        CheckIfCefIsInitialized();
        BrowserFactory.GetBrowserInstance(url, "browserName");

    }

    public void CheckIfCefIsInitialized()
    {
        if (!Cef.IsInitialized)
        {
            var settings = new CefSettings();
            var assemblyPath = Path.GetDirectoryName(new Uri(GetType().Assembly.CodeBase).LocalPath);

            settings.BrowserSubprocessPath = Path.Combine(assemblyPath, "CefSharp.BrowserSubprocess.exe");
            settings.ResourcesDirPath = assemblyPath;
            settings.LocalesDirPath = Path.Combine(assemblyPath, "locales");

            var osVersion = Environment.OSVersion;
            //Disable GPU for Windows 7
            if (osVersion.Version.Major == 6 && osVersion.Version.Minor == 1)
            {
                // Disable GPU in WPF and Offscreen examples until #1634 has been resolved
                settings.CefCommandLineArgs.Add("disable-gpu", "1");
            }

            //Perform dependency check to make sure all relevant resources are in our output directory.
            Cef.Initialize(settings, performDependencyCheck: false, cefApp: null);
        }
    }

}

我在这里获得了我的浏览器实例,并连接了要触发的事件。

public static class BrowserFactory
{

    public static ChromiumWebBrowser GetBrowserInstance(string _url, string browsername)
    {
        if (!BrowserContainer.CheckIfBrowserExists(browsername))
        {
            ChromiumWebBrowser _browser = new ChromiumWebBrowser(_url);
            _browser.LoadingStateChanged += BrowserEvents.OnLoadingStateChanged;
            BrowserContainer.AddDataHolder(browsername, new DataBrowserHolder { BrowserName = browsername, ChromiumWebBrow = _browser });

            return _browser;
        }

        return null;

    }
}

Browserevent加载正确的页面。

    public static class BrowserEvents
{
    public static void OnLoadingStateChanged(object sender, LoadingStateChangedEventArgs args)
    {
        if (args.IsLoading == false)
        {
            ChromiumWebBrowser cwb = (ChromiumWebBrowser)sender;

            if (cwb.Address == "https://se.tradingview.com/")
            {
                BrowserActions.LogInToTradingView("xxxxx", "yyyyyyy", "loginbrowser");
            }
        }
    }
}

最后一次我的浏览器操作是线程空闲的,它只是在构建中,并且可以在atm运行。

  public static class BrowserActions
{
    public static void LogInToTradingView(string twusername, string twpassword, string browserName)
    {
        ChromiumWebBrowser _dataholder = BrowserContainer.GetDataHolderByName(browserName).ChromiumWebBrow;

        IFrame ifww = _dataholder.GetMainFrame();
        //    var lull = @"(function() { var serielength = TradingView.bottomWidgetBar._widgets.backtesting._reportWidgetsSet.reportWidget._data.filledOrders.length; return serielength; })();";
        //    JavascriptResponse _js = Task.Run(async () => { return await _browser.GetMainFrame().EvaluateScriptAsync(lull); }).Result;

        ifww.ExecuteJavaScriptAsync(@"(function() { window.document.getElementsByClassName('tv-header__link tv-header__link--signin js-header__signin')[0].click();})();");

        //  var loginusernamescript =  
        var loginpasswordscript = @"(function() { window.document.getElementsByClassName('tv-control-material-input tv-signin-dialog__input tv-control-material-input__control')[1].value= " + twpassword + "; })();";
        var clkloginbtn = @"(function() { document.getElementsByClassName('tv-button tv-button--no-border-radius tv-button--size_large tv-button--primary_ghost tv-button--loader')[0].click();})();";
        Thread.Sleep(300);
        ifww.ExecuteJavaScriptAsync(@"(function() { window.document.getElementsByClassName('tv-control-material-input tv-signin-dialog__input tv-control-material-input__control')[0].click();})();");
        Thread.Sleep(50);
        ifww.ExecuteJavaScriptAsync(@"(function() { window.document.getElementsByClassName('tv-control-material-input tv-signin-dialog__input tv-control-material-input__control')[0].value = '" + twusername + "';})();");
        Thread.Sleep(50);
        ifww.ExecuteJavaScriptAsync(@"(function() { window.document.getElementsByClassName('tv-control-material-input tv-signin-dialog__input tv-control-material-input__control')[1].click();})();");
        Thread.Sleep(50);
        ifww.ExecuteJavaScriptAsync(@"(function() { window.document.getElementsByClassName('tv-control-material-input tv-signin-dialog__input tv-control-material-input__control')[1].value = '" + twpassword + "';})();");
        Thread.Sleep(50);
        ifww.ExecuteJavaScriptAsync(@"(function() { document.getElementsByClassName('tv-button tv-button--no-border-radius tv-button--size_large tv-button--primary_ghost tv-button--loader')[0].click();})();");

    }

    public static string TakeScreenshot(string browserName)
    {
        try
        {
            Bitmap img = Task.Run(async () => { return await BrowserContainer.GetDataHolderByName(browserName).ChromiumWebBrow.ScreenshotAsync(); }).Result;
            //    object mgss = img.Clone();
            string baseen = ExtraFunctions.ToBase64String(img, ImageFormat.Png);
            return baseen;
        }
        catch (Exception e)
        {
            var x = e.InnerException;
            return null;
        }
    }

    public static string RunScriptInNamedBrowser(string browserName, string script)
    {
        try
        {
            string str = Task.Run(async () => { return await BrowserContainer.GetDataHolderByName(browserName).ChromiumWebBrow.GetMainFrame().EvaluateScriptAsync(script); }).Result.ToString();
            //    object mgss = img.Clone();
            return str;
        }
        catch (Exception e)
        {
            var x = e.InnerException;
            return null;
        }
    }
}

如何获取浏览器操作报告给控制器,以便我可以等待它们完成?

1 个答案:

答案 0 :(得分:1)

要进行Task异步操作以进行报告,可以使用Progress<T>Enabling Progress and Cancellation in Async APIs中详细说明了如何进行。关键是:

var progressIndicator = new Progress<int>(ReportProgress);

这将创建一个Progress<T>对象,该对象可以指示任务完成的程度,还可以按设置的时间间隔调用自定义方法(ReportProgress)。您可以根据需要创建自定义类,而不使用int

因此,您的浏览器操作可以使用进度报告方法向控制器报告,直到一切完成。