I'm a fairly new developer and this one has me stumped.
My WinForms application is a slideshow for websites that rotates through a list of URLs, fading-in/out on each transition by using a second form as a "curtain". It's meant to run for an indefinite period of time but consistently hangs on the transition after running for a couple of days.
Form1:
HttpWebResponse response = null;
List<Slide.Doc> sList = null;
bool repeatSlideshow = true;
bool pageLoaded = false;
double curtainAnimStep = 0.05;
int errorCount = 0;
public Form1()
{
    InitializeComponent();
    CursorShown = false;
    this.Visible = true;
    this.FormBorderStyle = FormBorderStyle.None;
    this.WindowState = FormWindowState.Maximized;
    webBrowser1.ScrollBarsEnabled = false;
    webBrowser1.ScriptErrorsSuppressed = true;
    Slideshow(environment, channel);
}
public void Slideshow(string environment, string channel)
    {           
        while (repeatSlideshow)
        {
            try
            {
                sList = Slide.convertJSONToSlide(Slide.getParams(environment, channel));
            }
            catch (Exception)
            {
                Form2 curtain = new Form2(curtainAnimStep);
                curtain.Show();
                waitForFade(curtain, 1);
                displayError();
                raiseCurtain(curtain, curtainAnimStep);
                waitForFade(curtain, 0);
                curtain.Dispose();
                waitAround(30);
                continue;
            }
            foreach (Slide.Doc s in sList)
            { 
                bool slideWasDisplayed = false;
                Form2 curtain = new Form2(curtainAnimStep);
                curtain.Show();
                waitForFade(curtain, 1);
                slideWasDisplayed = displaySlide(s.URL_TEXT);
                if (slideWasDisplayed == false)
                {
                    webBrowser1.DocumentText = "<html><body style='background-color: #1C1C1C;'></body></html>";
                    redrawPage();
                }
                raiseCurtain(curtain, curtainAnimStep);
                waitForFade(curtain, 0);
                curtain.Dispose();
                if (slideWasDisplayed == true)
                {
                    waitAround(s.DISPLAY_SEC);
                }
            }
            if (errorCount == sList.Count)
            {
                Form2 curtain = new Form2(curtainAnimStep);
                curtain.Show();
                waitForFade(curtain, 1);
                displayError();
                raiseCurtain(curtain, curtainAnimStep);
                waitForFade(curtain, 0);
                curtain.Dispose();
                waitAround(30);                  
            }
            errorCount = 0;
            Utilities.Web.WebBrowserHelper.WebBrowserHelper.ClearCache();
        }
    }
    public bool displaySlide(string slideUrl)
    {
        HttpWebRequest request = (HttpWebRequest)WebRequest.Create(slideUrl);
        request.Timeout = 1000;
        try
        {
            response = (HttpWebResponse)request.GetResponse();
            webBrowser1.Navigate(slideUrl);
            redrawPage();
            response.Dispose();
            return true;
        }
        catch (WebException)
        {
            errorCount++;
            return false;
        }
    }
    public void redrawPage()
    {
        while (pageLoaded == false)
        {
            Application.DoEvents();
        }
        webBrowser1.Invalidate();
        Application.DoEvents();
        pageLoaded = false;
    }
    public void raiseCurtain(Form curtain, double curtainAnimStep)
    {
        while (curtain.Opacity > 0)
        {
            curtain.Opacity -= curtainAnimStep;
            Application.DoEvents();
            System.Threading.Thread.Sleep(10); // How long between shifts in opacity (NOT interval between slides)
        }
    }
    public void waitAround(int duration)
    {
        DateTime dt2 = DateTime.Now;
        while (dt2.AddSeconds(duration) > DateTime.Now)
        {
            Application.DoEvents();
        }
    }
    public void waitForFade(Form curtain, int finalOpacity)
    {
        while (curtain.Opacity != finalOpacity)
        {
            DateTime dt = DateTime.Now;
            dt = dt.AddSeconds(1);
            while (dt > DateTime.Now)
            {
                Application.DoEvents();
            }
        }
    }
    private void webBrowser1_DocumentCompleted(object sender, WebBrowserDocumentCompletedEventArgs e)
    {
        pageLoaded = true;
    }
Form2:
public Form2(double animStep)
        {
            InitializeComponent();
            this.AnimStep = animStep;
        }
        public double AnimStep { get; set; }
        private async void Form2_Load(object sender, EventArgs e)
        {
            while (Opacity < 1.0)
            {
                await Task.Delay(10);
                Opacity += AnimStep;
            }
            Opacity = 1;
        }
I've been working on this for a long time, but I have to admit that I genuinely don't even know what I should be looking for at this point.
Could the use of Application.DoEvents be responsible? Leaving them out breaks the application, but I can't figure out an alternative appproach.