views:

1338

answers:

1

I'm writing a Toast that needs to be thread-safe as it's being used to report the status of asynchronous socket input. I've tried to make it thread-safe but the toasts are still locking up.

    public static void Show( string message ) {
        Toast toast = new Toast( message );
        toast.ShowAction();
    }

    private delegate void InvokeCallback();

    public void ShowAction() {
        if ( InvokeRequired ) {
            Invoke( new InvokeCallback( ShowAction ) );
        }
        else {
            Show();
        }
    }

I want to be able to display them easily like a message box, i.e. Toast.Show("Status changed");. Any help would be greatly appreciated.

+1  A: 

Your issue is the fact that the Toast is being CREATED on another thread. What you'll likely need to do is have a "target" on the main UI thread where you can Invoke() the creation AND showing of the Toast, keeping all UI on the same thread.

EDIT

If you need to be able to keep this on another thread, your only other option is to create another thread with a message loop.

Thread t = new Thread();

t.SetApartmentState(ApartmentState.STA) // Required for a UI thread

As to the implementation of dispatching tasks and messages to this thread, I'll leave that up to you. You'll need to call Application.Run() at the start of it in order to start your message loop.

And, as always, you'll have to be sure to Invoke() any operations from your Toast (or anything on this thread) that may interact with the main UI thread.

Adam Robinson
Is there any other way to get this done? This is part of a plugin system and thus I have no access to the main UI thread.
You can run, on the same thread that creates the form, a message loop around the form. Simply do: Application.Run(form); Note that the form is now in control, so you need the form to close itself when appropriate.
Lasse V. Karlsen
@Taylor: See edit.
Adam Robinson
@lassevk: NO NO NO! Never start a message loop on a thread that you don't start. This could have disastrous consequences!
Adam Robinson