Re: Passing reference of the main thread control

Tech-Archive recommends: Repair Windows Errors & Optimize Windows Performance



On Fri, 29 May 2009 03:33:14 -0700, ragid <ragid@xxxxxxxx> wrote:

Thanks,
I'm not sure that I'm doing everything completely right but my current code
works fine with Invoke() and delegates, but both threads are in the same
module and there is no problem of references. In my post I describe a new
situation where I have to invoke the method from a dll- where all my problems begin..
I'll paste the relevant code here...
the delegate code-

(the class name is VLC)
puplic delegate void SimbuttonCaptureStream(

string client_location, string client_url, uint client_port);

public SimbuttonCaptureStream myDelegate;

public void SimbuttonCaptureStream_Click(

string client_location, string client_url, uint client_port)

{

logger.Debug(System.Reflection.MethodBase.GetCurrentMethod().Name);

vlcUserControl1.PrecomputeCrop(ClientSize, 50, 100, 50, 50);

string AddAndPlay_First_Parameter = @"screen://";

..................here comes some other code

}

The code that invokes the method SimbuttonCaptureStream_Click follows

VLC.MainForm.TheMainForm.Invoke(

VLC.MainForm.TheMainForm.myDelegate, new object[] { second_paramter,
third_paramter, fifth_parameter });

Can you demonstrate in my code what should I do?

You left out the all-important initialization of "myDelegate", and the question is still fairly vague. However, assuming that it's set to a delegate instance created from the "SimbuttonCaptureStream_Click()" method, it seems likely to me that you'll want to do two things:

-- Move the call to Control.Invoke() into your callback method ("SimbuttonCaptureStream_Click")
-- pass the delegate instance that you would have assigned to VLC.MainForm.TheMainForm.myDelegate, to the DLL instead

Then, the DLL can invoke the delegate directly (not to be confused with calling the Control.Invoke() method), and the method referenced by the delegate will handle the call to Control.Invoke().

For example, in your MainForm class:

public void SimbuttonCaptureStream_Click(
string client_location, string client_url, uint client_port)
{
TheMainForm.Invoke((MethodInvoker)delegate
{
logger.Debug(System.Reflection.MethodBase.GetCurrentMethod().Name);
vlcUserControl1.PrecomputeCrop(ClientSize, 50, 100, 50, 50);

string AddAndPlay_First_Parameter = @"screen://";

// ..................here comes some other code
});
}

Then in the DLL:

public void SomeMethodThatHasToCallYourFormMethod(SimbuttonCaptureStream callback)
{
string client_location;
string client_url;
uint client_port;

// initialize the variables above somehow
// do some stuff (whatever)
// do some other stuff (whatever)
// then, call the callback:
callback(client_location, client_url, client_port);
}

From your MainForm class, you'd call the DLL like so:

SomeMethodThatHasToCallYourFormMethod(SimbuttonCaptureStream_Click);

or (more explicitly, but equivalent to the above):

SomeMethodThatHasToCallYourFormMethod(new SimbuttonCaptureStream(SimbuttonCaptureStream_Click));

If the DLL is not going to execute the callback immediately during whatever method the MainForm class calls, but rather needs to do it later, then you can simply save the callback reference to a member field in the DLL code and having the same delegate type SimbuttonCaptureStream, for use later.

An alternative to saving the callback reference in the DLL code would be to have the DLL code declare an event, to which the MainForm can subscribe directly. For example:

In the DLL:

public event SimbuttonCaptureStream Callback;

public void SomeMethodThatHasToCallYourFormMethod()
{
string client_location;
string client_url;
uint client_port;

// initialize the variables above somehow
// do some stuff (whatever)
// do some other stuff (whatever)
// then, raise the event:

SimbuttonCaptureStream handler = Callback;

if (handler != null)
{
handler(client_location, client_url, client_port);
}
}

In the MainForm, any time before the callback has to happen:

MyDLLClass.Callback += SimbuttonCaptureStream_Click;

Again, in this scenario you need to move the call to Control.Invoke() into the SimbuttonCaptureStream_Click method, as I described above.

The main advantage to the event pattern as opposed to the callback pattern is that it much more easily allows for multiple callbacks for the same event. It's also somewhat more self-documenting. You may or may not find those advantages compelling for this particualr scenario.

And again, all of this is reasonably well-documented on MSDN. You should read the documentation on declaring events and using delegates in C#, especially comparing the samples there to the code I've shown above so that you understand what parts are general to events and delegates, and what parts have specifically to do with the separation of modules (main program and DLL).

Pete
.



Relevant Pages

  • Re: Unmanaged DLL Callback - Program Unexpectedly Quits
    ... I had a similar problem when using a Fortran DLL that was doing callbacks into a VB.Net host. ... I looked at the callbacks for a long time without making any progress because the problem turned out to be unrelated to the callback. ... As long as a reference to the delegate remains "in scope" during the processing then the delegate shouldn't be garbage collected. ... But I DO worry about what happens if garbage collection of other things causes the object containing the callback procedure to be moved between the invocation and completion of the DLL. ...
    (microsoft.public.dotnet.languages.vb)
  • Re: New to Delegates. Having Issues
    ... My InterOp complies fine with no ... Here is the lines of code where I use my Delegate in my InterOp: ... string reason, string phoneNumber, ... A callback was made on a garbage collected delegate of type ...
    (microsoft.public.dotnet.languages.csharp)
  • Dynamic discovery of delegates
    ... I have an application that loads assemblies at runtime. ... I have an object with delegate defined as follows: ... public delegate StringChanged(strNewValue as string) ... I then have a method to assign a callback to this delegate, ...
    (microsoft.public.dotnet.languages.vb)
  • Dynamic Discovery of Delegates
    ... I have an application that loads assemblies at runtime. ... I have an object with delegate defined as follows: ... public delegate StringChanged(strNewValue as string) ... I then have a method to assign a callback to this delegate, ...
    (microsoft.public.dotnet.general)
  • Re: ctypes and reading value under pointer passed as param of a callback
    ... > I'm using C dll with py module and wanna read value (buffer of bytes) ... > returned in py callback as parameter passed to dll function. ... The callback receives a pointer instance. ... and how to convert a list of bytes to py string or int ?? ...
    (comp.lang.python)