G
gregbacchus
I am trying to make a window that pops up, to show that my application
is busy. I want it to be able to be called from anywhere, any thread,
so I put it as a static method in a class.
Code listed below.
The problem is, no matter what I can think of doing, I get the
following exception:
"Controls created on one thread cannot be parented to a control on a
different thread"
Trace:
at System.Windows.Forms.Control.MarshaledInvoke(Control caller,
Delegate method, Object[] args, Boolean synchronous)
at System.Windows.Forms.Control.Invoke(Delegate method, Object[]
args)
at UI.Waiter.Busy(Object waitOn)
or i used to get this with a slightly different configuration (same
exception):
Trace:
at System.Windows.Forms.ControlCollection.Add(Control value)
at System.Windows.Forms.ControlCollection.Add(Control value)
at UI.Controls.WaitForm.InitializeComponent()
at UI.Controls.WaitForm..ctor()
at UI.Waiter..cctor()
Anyone got any ideas... or am i going about it the wrong way all
together!?
Cheers
Greg
----- CODE -----
using System;
using System.Collections;
using System.Threading;
using System.Windows.Forms;
namespace UI
{
/// <summary>
/// Summary description for Waiter.
/// </summary>
public sealed class Waiter
{
private static ArrayList _list = new ArrayList();
private static Mutex _lock = new Mutex();
private static Controls.WaitForm _form = null;
private static Form _parent = null;
public static Form Parent { get { return _parent; } set { _parent =
value; } }
private Waiter()
{
}
private delegate void BusyDelegate( object obj );
public static void Busy( object waitOn )
{
if( _parent != null )
_parent.Invoke( new BusyDelegate( InternalBusy ), new object[] {
waitOn } );
}
private static void InternalBusy( object waitOn )
{
// this has to be done here for threading reasons
if( _form == null )
_form = new Controls.WaitForm();
// show the waiting form
_lock.WaitOne();
try
{
_list.Add( waitOn );
if( _list.Count == 1 )
{
_form.Restart();
_form.Show();
System.Windows.Forms.Application.DoEvents();
}
}
finally
{
_lock.ReleaseMutex();
}
}
public static void Ready( object waitOn )
{
_lock.WaitOne();
try
{
_list.Remove( waitOn );
if( _list.Count == 0 )
{
_form.Hide();
}
}
finally
{
_lock.ReleaseMutex();
}
}
}
}
is busy. I want it to be able to be called from anywhere, any thread,
so I put it as a static method in a class.
Code listed below.
The problem is, no matter what I can think of doing, I get the
following exception:
"Controls created on one thread cannot be parented to a control on a
different thread"
Trace:
at System.Windows.Forms.Control.MarshaledInvoke(Control caller,
Delegate method, Object[] args, Boolean synchronous)
at System.Windows.Forms.Control.Invoke(Delegate method, Object[]
args)
at UI.Waiter.Busy(Object waitOn)
or i used to get this with a slightly different configuration (same
exception):
Trace:
at System.Windows.Forms.ControlCollection.Add(Control value)
at System.Windows.Forms.ControlCollection.Add(Control value)
at UI.Controls.WaitForm.InitializeComponent()
at UI.Controls.WaitForm..ctor()
at UI.Waiter..cctor()
Anyone got any ideas... or am i going about it the wrong way all
together!?
Cheers
Greg
----- CODE -----
using System;
using System.Collections;
using System.Threading;
using System.Windows.Forms;
namespace UI
{
/// <summary>
/// Summary description for Waiter.
/// </summary>
public sealed class Waiter
{
private static ArrayList _list = new ArrayList();
private static Mutex _lock = new Mutex();
private static Controls.WaitForm _form = null;
private static Form _parent = null;
public static Form Parent { get { return _parent; } set { _parent =
value; } }
private Waiter()
{
}
private delegate void BusyDelegate( object obj );
public static void Busy( object waitOn )
{
if( _parent != null )
_parent.Invoke( new BusyDelegate( InternalBusy ), new object[] {
waitOn } );
}
private static void InternalBusy( object waitOn )
{
// this has to be done here for threading reasons
if( _form == null )
_form = new Controls.WaitForm();
// show the waiting form
_lock.WaitOne();
try
{
_list.Add( waitOn );
if( _list.Count == 1 )
{
_form.Restart();
_form.Show();
System.Windows.Forms.Application.DoEvents();
}
}
finally
{
_lock.ReleaseMutex();
}
}
public static void Ready( object waitOn )
{
_lock.WaitOne();
try
{
_list.Remove( waitOn );
if( _list.Count == 0 )
{
_form.Hide();
}
}
finally
{
_lock.ReleaseMutex();
}
}
}
}