Syncing Delphi NonVisualPlugin threads with WinForms Host

There is an example of how to sync calls between a .NET NonVisualPlugin with a Delphi host.
Would you please provide an example for how to do the opposite direction, where a Delphi NonVisualPlugin syncs with a WinForms host (i.e., the sync window code ninjutsu on the Delphi side)?

For reference, I’m having trouble with threaded callbacks from a Delphi NonVisualPlugin to a WinForms host. I get this message when receiving a callback from the plugin to the host and trying to update the UI:

07-AM

I suppose I might be able to post something to the UI thread from the WinForms side in the callback method, instead of syncing the NonVisualPlugin, but this doesn’t feel like a good solution to me.

Sync approach shown in the Synchronizing in NonVisualPlugins section of the article you are referring to is just a workaround with invisible window and its Invoke method.

In general approach it to ensure that the proper GUI thread is used (via .NET method Invoke or via Delphi’s Synchronize method). Why it is better? Because you have to ensure that the callback invocation from a plugin won’t crash the host app due to cross-thread GUI access. In other words

is actually the best approach.

As of now, I’m checking InvokeRequired on UI controls:

// My custom interface callback from the Delphi plugin to the WinForms host
public void OnConvertProgress(int Percent)
{
    try
    {
        var text = "Progress: " + Percent + "%";
        if (label1.InvokeRequired)
        {
            label1.Invoke(new Action(() => label1.Text = text));
        }
        else
        {
            label1.Text = text;
        }
    }
    catch (Exception e)
    {
        Console.WriteLine(e.Message);
    }
}

Just so I’m clear, the best way make sure that the plugin doesn’t crash the host is to handle the thread check and control updates on the WinForms host side? Thanks.

In general you do not control what the plugin does (ie does it sends its response in UI thread or not). So you’d anyway need this code to make sure that the plugin doesn’t misbehave. Also the plugin doesn’t know how the data it sends will be consumed (f.e. these data would be saved into database instead of being displayed in UI), so there might be no need in any UI thread synchronization at all.

You could always use the .Invoke call w/o checking the .InvokeRequired. That would keep the code cleaner and the performance impact is not noticeable here.

1 Like

Thanks, appreciate the support.