Click here to Skip to main content
15,894,720 members
Please Sign up or sign in to vote.
4.00/5 (1 vote)
See more:
I'm fairly new to c#, and especially multi-threading, and this is really doing my head in. It seems it should be a simple answer but I don't see it.

Let's say I have a c# library that runs certain procedures in it's own thread. This thread creates a Bitmap which I want to pass back to the application that uses the library. So I pass the Bitmap through a delegate. Now, this Bitmap may be displayed in a PictureBox etc on the main form, or it may not. If it always was a Control (eg, a PictureBox), then I could pass a reference of the control to the library's thread and use Control.Invoke to update the control, and remain thread-safe.

But what if it wasn't a windowed control? How do I go about accessing/using this Bitmap in any way I like from the main app and still remain thread-safe? I don't expect other users of my library to have to deal with lock() etc. So how is this done? It seems I would have to block the library's thread somehow until the delegate has returned. But how?

Edit: I read my posted message and it doesn't make sense. What I'm asking is:
If I have a separate thread which communicates with the UI thread through a delegate, how can I make that delegate run in the UI thread when it may not be associated with a Control? Obiously Control.Invoke can't be called.
Posted
Updated 26-Oct-10 1:15am
v2

I answered this question a while ago. The first question was about delegates and also provided extra information about "Extra information about Invoke". It would be recommended to read it completely because it will give you some good info I think.

PLZ HELP ME EXPLAINING[^]

Good luck!
 
Share this answer
 
v2
Comments
Rajesh Anuhya 26-Oct-10 7:36am    
Good Answer...
jabbawok 26-Oct-10 17:50pm    
Ok I read your other answer in the other thread but I still don't get it.

If I was passing a Windows.Forms.Control to the non-UI thread, then I could use a wrapper function for updating via Control.Invoke (checking InvokeRequired first of course). But I don't want to have to pass a Control. I may want to just grab the Bitmap and paint it directly on a form. So I'm passing a delegate to the non-UI thread, which gets "fired" by the backgound thread whenever another Bitmap is available. But doesn't this delegate need to run in the UI-thread, even if it's just to paint on the form? If so, how is it done? I don't have a reference to a Control to call Invoke/InvokeRequired on in this case.
E.F. Nijboer 27-Oct-10 7:22am    
But you say you may want to draw the bitmap directly on a form. What do you think Form descends from? ;-)
http://msdn.microsoft.com/en-us/library/system.windows.forms.form.aspx
An update to my question.

As explained previously I needed this to be "universal". In other words the background thread shouldn't have any idea on how it will be used, or require a Control to be passed to the thread so Control.Invoke can be called.

The answer was to use the ISynchronizeInvoke interface directly. I found some sample code at StackOverflow and am using it like this (a different project, but same problem/solution):

C#
private void HandleSyncCallback(Bitmap tile, int left, int top, CancelRenderArgs e)
{
    Delegate[] handlers = _renderArgs.trCallBack.GetInvocationList();
    foreach (var del in handlers)
    {
        ISynchronizeInvoke target = del.Target as ISynchronizeInvoke;
        if ( (target != null))
        {
            if (target.InvokeRequired)
            {
                target.Invoke(del, new object[] {tile, left, top, e});
            }
            else
            {
                del.DynamicInvoke(new object[] {tile, left, top, e});
            }
        }

    }
}


Works a treat.

Thanks,
Dave.
 
Share this answer
 

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)



CodeProject, 20 Bay Street, 11th Floor Toronto, Ontario, Canada M5J 2N8 +1 (416) 849-8900