We've implemented our main code functionality in a C++ Dll then written a C# UI on top. This works fine most of the time, but in areas where we want the UI to report the progress of a function in C++ we're having some performance problems.
We pass a pointer to a C# function down to the Dll to use for progress updates. When it's called we use InvokeRequired and Invoke() to make sure the callback is thread-safe. Measured from the C++ side, this can take anything between 16ms and 180ms. Is there any way of reducing the time this takes?
One of these callbacks passes the location of a line to be drawn on the screen. This drawing currently very slow - I assume the invoked functions are queuing up and taking time to be drawn in C#. I can see two ways of dealing with this: 1. Change the callback to send a list of lines and allow the lines to queue up in C++ whilst waiting for the previous call to C# to complete. 2. Adding the lines to a queue in C# (preferably without calling Invoke) then drawing all lines that are available at once. Any suggestions on how to do this, whether both options are required, or alternative methods?
Thanks for any开发者_如何学编程 and all help.
You can use BeginInvoke
instead of Invoke
. Invoke
waits for the function to return, while BeginInvoke
allows the function to run parallel to the current thread.
Your problem is not the callback but likelys the invoke. Invoke is a potentially expensive operation. If you ahve a thread change there, it WILL take time. A lot. You alsoa re putting the drawing operations into the same thread, so the callback will block until those are finished.
What you can do:
- BeginInvoke - basically the callback erturns early, another thread does the drawing.
- Reduce the number of invokes, basically batching your requests. This can be done OUTSIDE The C++ dll - have the callback put the corodinates into a queue, then the queue in a separate thread call BeginInvoke.
Basically, your single threaded UI and the requirement of thread switching via dispatcher kill you, totally within the C# area.
At the end, your question is badly worded. C++ & C# has nothing to do with the problem, you would have the same issue with C# only. You have an API making callbacks into the UI that needs to switch threads (Invoke) and do UI operations, and this leads yo t he callback taking more time than you want. Replace C## with Smalltalk, Assembler, C#, Visual basic and the problem stays 100% the same.
As far as I understand your question, there is only one line, which should be drawn. But its coordinates are frequently generated in the unmanaged part and sent to C# to update the graphical representation? Consider enabling the drawing method to cancel itself. So when - while drawing a line - new coordinates arrive, discard the current line and just draw the new coordinates. That way you may get rid of the need to implement any queueing at all.
@Edit: I tend to the suggestion to better query all necessary data from the C++ part by C#. It sounds like you are calling back to .NET very often in order to control some visual output. But this should be done from .NET (which knows much better, how often it is possible at all). So, querying all data from C++ in a user defined structure may help.
精彩评论