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.