This is a fairly straight forward question. I have a C# WPF MVVM application that call a C++ DLL to do some compilation/crunching. To update the UI C# application for progress updates I am using callback delegates.
public static class Callbacks
{
public static ConsoleCallback ConsoleOutputCallback { get; set; }
[UnmanagedFunctionPointer(CallingConvention.StdCall)]
public delegate void ConsoleCallback(string message);
}
where the implementation is
Callbacks.ConsoleOutputCallback = (message) =>
{
console.Document.Text += message;
};
where Document
is of type TextDocument
. I am then passing this object into the C++ to be able to invoke it and update the UI. This works great, however, for one control I am getting a standard
A first chance exception of type 'System.InvalidOperationException' ... TextDocument can be accessed only from the thread that owns it.
Now, I understand this error. To get around it I have done the following
TaskScheduler scheduler = TaskScheduler.FromCurrentSynchronizationContext();
Callbacks.ConsoleOutputCallback = (message) =>
{
Task.Factory.StartNew(() =>
{
console.Document.Text += message;
}, CancellationToken.None,
TaskCreationOptions.None,
scheduler);
};
which works. However, it would be nicer to look at if I could do a similar thing that I could do with a Control
(which TextDocument Document
is not) like
public static void PerformSafely<T>(this Control target, Action<T> action, T parameter)
{
if (target.InvokeRequired)
target.Invoke(action, parameter);
else
action(parameter);
}
but I cannot do this with TextDocument
as it does not inherit from Control
. Is there a nicer way to do what I am doing?