using System; using System.Collections.Generic; using System.Linq; using System.Text; using Inet.Viewer.WinForms; using NUnit.Framework; using System.Threading; using System.Windows.Forms; using System.ComponentModel; namespace Inet.Viewer.test.WinForms { [ToolboxItem(false)] internal class ReportViewShowError : ReportView { internal Exception exception; private bool assertFinish; private List stacktraces = new List(); internal ReportViewShowError() { } /// /// /// /// internal ReportViewShowError(IRenderData data) : this(data, true) { } internal ReportViewShowError(IRenderData data, bool waitOnThreads) : base() { ReportData = data; if (waitOnThreads) { AssertException(3); } } internal override void ThreadFinished() { lock (this) { stacktraces.Add(new System.Diagnostics.StackTrace().ToString()); } } /// /// /// /// public override void ShowError(Exception ex) { if (this.exception == null) { this.exception = ex; if (this.assertFinish) { base.ShowError(ex); } } } internal void AssertException(int threadCount) { WinFormsMessageLoop.Activate(this); // start the bacjground threads of the GUI for nunit for (int i = 0; i < 1000; i++) { if (exception != null) { this.assertFinish = true; throw exception; } lock (this) { Console.WriteLine("Waiting for " + threadCount + " threads (" + stacktraces.Count + " done)..."); if (this.stacktraces.Count == threadCount) { this.assertFinish = true; return; } if (this.stacktraces.Count > threadCount) { this.assertFinish = true; Assert.AreEqual(threadCount, this.stacktraces.Count, "ThreadCount\n" + string.Join("\n", stacktraces.ToArray())); } } Thread.Sleep(2); } this.assertFinish = true; Assert.AreEqual(threadCount, this.stacktraces.Count, "ThreadCount\n" + string.Join("\n", stacktraces.ToArray())); } } static class WinFormsMessageLoop { private static readonly object mylock = new object(); private static Form theForm; private static Form GetForm() { lock (mylock) { if (theForm == null) { Thread thread = new Thread(MessageLoop); thread.SetApartmentState(ApartmentState.STA); thread.Name = "WinForms Message Loop"; thread.IsBackground = true; thread.Start(); while (theForm == null && thread.IsAlive) { Thread.Sleep(1); } } } return theForm; } private static void MessageLoop() { using (Form form = new Form()) { form.CreateControl(); IntPtr handle = form.Handle; theForm = form; Application.Run(); } } /// /// Aktivate the event thread /// /// internal static void Activate(Control control) { GetForm().Invoke((MethodInvoker)delegate { IntPtr handle = control.Handle; }); } } }