I am using TreeViewer and creating Job to refresh Treeview that is added 4k - 5k nodes. In Refresh Job, I call Display.getDefault().asyncExec to execute getTreeViewer().refresh() method. However, I have faced the problem that getTreeViewer().refresh() has to wait 4000ms or more than that to run. This is in Ubuntu and Windows has to wait more than 30000ms.
i don't know why it has to wait for long time to execute.
asyncExec runs as soon as possible on the SWT User Interface thread. So if it is being delayed something else must be using that thread. Since you have a large tree it is probably the TreeViewer building the tree that is causing the delay (unless you are running something that take a long time in the UI thread).
For a large tree you may need to look at creating the tree with the SWT.VIRTUAL style and use a ILazyTreeContentProvider content provider.
Related
I an implementing an IDE based on XCode design. It has been a lot of learning.
I need to update UI without blocking it.
I already have a pair of threads
using Grand Central Dispatch.
Basically I have an Interpreter, and an UI with an codeView (NSTextView) and an outputView (NSTextView). When I press play/run the IDE runs the code. It launches two threads, both with an while loop. One to run the program, the other to update the UI from any output or message sent from interpreter.
Something like this:
// program execution thread
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0),
{
self.interpreter_s.execute()
});
// update UI while interpreter thread is running
dispatch_async(dispatch_get_main_queue(),
{
self.updateUIWhileInterpreterRunningThread()
});
}
They both communicate one with the other, so they have concurrency.
According with the research I've made, it's recommended to update the UI using the main_queue(). However, when I do this, it blocks the UI from receiving user input.
In my case, this causes the stop button to be rendered useless.
So I need an way to update the UI from the updates from interpreter thread without blocking the Views from user input.
Any thoughts?
I have huge preference from an solution already using Grand Central Dispatch. I also want to avoid dispatching UI Updates from the interpreter thread, since this could be terribly inefficient in this particular case.
I have a little issue with a form in a delphy XE2 application:
It's an old issue on this application and i have begin to work on it just since a little time.
When the user choose to launch the process with a button's event, my application launch a connexion with an OPCServer , an SQLServer and construct the form for a good following of data take on the tow servers.
The construction of my form involves a blockage of the interface (for approximately 15 sec) because of lot's of data which are necessary for make it.
When it freeze, if the user want drag the form, she go far away, and usually with the TMainMenu which go out of the screen. After that, it's impossible to use the application because we can't drag and we need to close and re-open.
In the old version, the form be already construct before the connexion. So the modification for a dynamic form isn't in link with this issue.
Life of my event :
-Open connexion with OPC Server
-Open SQL Connexion
-Send SQL Command Text
-FieldByName('') for update my UI (Button.Caption// TPage.TStaticText.Caption // TPage.Label1.Caption)
-FieldByName('') for update an array of record
-Close SQL Connexion
-Open SQL Connexion
-Send SQL CommandText
-FieldByName('') for update an other array of record
-Panel.Visible(false)
-TPage.Panel.Show;
-TPage.Panel.BringToFront;
So I haven't MainForm modification can change its position.
I'm a young developer, so I don't know why it moving and what I can make for repair that...
If you want a part of code, ask me what and i edit this, it's very long and i don't want spam answer.
Thank's for read.
The core of your problem is that you have a lengthy process (form construction) which completely blocks the main thread so your application isn't able to process normal Windows messages at the same time. That is why when you move your application it doesn't properly update its interface.
Now based on your description you already have this form construction process split into multiple steps so you could call Application.ProcessMessages between them.
This will force your application to update its UI part.
But beware calling Application.ProcessMessages often could hurt your application performance quite a bit. Why? It is usually a lengthy process because it forces your application to process all the messages that are in its queue.
Normally not all of these messages get processed as soon as they arrive. Windows groups them in the message queue by their priority list, making sure that high priority messages like WM_PAINT are processed as soon as possible while some other low priority messages like demand for application to respond to OS so that OS can see if the application is still working are mostly processed when application is idle or when they are in queue for certain amount of time.
So that is why Application.ProcessMessages can be so slow as it forces your application to process all messages regardless of their priority.
Also bear in mind that using Application.ProcessMessages can in certain scenarios actually become a bit dangerous.
Let me give you an example:
Lets say that clicking on a button starts a lengthy job which can take some time to finish. Now in order to allow your form to be updated you call Application.ProcessMessages in certain intervals. So far it is all good. But what happens if user clicks on that button again?
Since you are calling Application.ProcessMessages which forces your application to process all the messages and since clicking on button creates a MouseClick message which then fires buttons OnClick event which then executes the OnClick method that has been assigned to buttons OnClick event in the end this will cause the same method that was executed on first button click to be executed again.
So now you have this method partially done from first button click and same method executing again for second mouse click. Now the method that was executed from the second click will finish first and then the method that was started from first button click but was interrupted with Application.ProcessMessages handling the second button click will continue its execution to the end.
This all can lead to strange bugs which are hard to track, because you as a programmer normally don't predict that your end user might have clicked the button twice.
So to avoid this I strongly recommend you implement some safeguard mechanisms to prevent such scenarios by temporarily disabling a button for instance.
But the best solution is always to show your user that your application is working which in most cases will dissuade them from clicking the button again, but unfortunately not always.
You should also take a good care when dynamically constructing a form to enable the controls only after all of the controls have been successfully constructed. Failing to do so the user might click on one of your controls and that control could attempt to access some other control which hasn't yet been created at the time. The result hard to track bug which causes Access Violation.
You might also consider showing a splash screen at start instead of half built form. Why?
For once it is much nicer to see and it tells your users to wait a bit. And for second having main form hidden until it is fully created makes sure that user won't be doing any clicks on it prematurely.
I'm using the Scala plugin, and it sometimes likes to hang and spin a rainbow wheel (Mac wait icon) for a long time. It's very annoying. Is there something like a "Control C" for the current thread? I'd like a way to tell Eclipse to kill the current UI command. This would help when use plugins that are not as polished as the one for Java.
There is no such feature and I would not hold your breath waiting for one. Unlike system processes that exist independent of each other, threads are entangled. Force killing a thread is very likely to corrupt various data structures and leave Eclipse process in a bad state.
Various API techniques exist to allow for cancellation of an operation, but they all rely on the running operation to actively check for cancellation request and safely shutdown. Not much help for dealing with unpolished plugins, since graceful handling of cancellation in all cases tends to be implemented as part of polishing.
One of the new performance enhanchements for .NET 4.5 is the introduction of the 'MultiCode JIT'.
See here for more details.
I have tried this, but it seems to have no effect on my application.
The reason why I am interested is that my app (IronScheme) takes a good long time to startup if not NGEN'd, which implies a fair amount of JIT'ng is involved at startup. (1.4 sec vs 0.1 sec when NGEN'd).
I have followed the instructions on how to enable this, and I can see a 'small' (4-12KB) is created. But on subsequent startup, it seems to have absolutely no effect on improving the startup time. It is still 1.4 sec.
Has anyone actually seen (or made) this work in practice?
Also, are there any limitations on which code will be 'tracked'? Eg: assembly loading contexts, transient assemblies, etc. I ask this as the created file never seems to grow, but I am in fact generating a fair amount of code (in a transient assembly).
One bug that I did encounter was that SetProfileRoot does not seem to understand a / as a path separator, make sure to use \ .
The rule of thumb we use at Microsoft is that Multicore JIT gets you about half way towards NGEN startup performance. Thus if your app starts in 0.1 seconds with NGEN and 1.4 seconds without NGEN, we would expect Multicore JIT startup to take about 0.75 seconds.
That being said, we had to put some limitations in place to guarantee that program execution order is the same with and without MCJ. MCJ will sometimes pause the background thread waiting for modules to be loaded by the foreground thread, and will abort background compilation if there is an assembly resolve or module resolve event.
If you want to find out what's happening in your case, we have ETW (Event Tracing For Windows) instrumentation of the MCJ feature and we will be releasing a version of PerfView soon which will be able to collect these events by if you take a trace of your app startup.
Update: PerfView has been updated to be able to show background JIT information. Here are the steps to diagnosing with the latest version (1.2.2.0):
Collect a trace using PerfView of your application startup, either using Collect->Run or Collect->Collect from the main PerfView menu.
Assuming you used Collect-> Run, put the name of your .exe in the Command text box, pick a filename (i.e. IronScheme.etl), select Background JIT from Advanced Options, and click Run Command.
Close your application and double click on the IronScheme.etl file that gets generated.
Double click on the JIT Stats view in the list underneath IronScheme.etl, you should see something like this in the view that pops up:
This process uses Background JIT compilation (System.Runtime.ProfileOptimize)
Methods Background JITTed : 2,951
Percent # Methods Background JITTed : 52.9%
MSec Background JITTing : 3,901
Percent Time JITTing is Background : 50.9%
Background JIT Thread : 11308
You can click on "View Raw Background Jit Diagnostics" to see all of the MCJ events in excel. One question I forgot to ask: are you running this on a multicore machine or multicore VM? It is a common mistake to test out MCJ in a VM that only has a single logical processor.
Calling Activator.CreateInstance during startup seems to kill MCJ?
Or rather that triggered an Assembly Resolve, which completely seems to stop MCJ. And never work after that. Maybe the MSDN docs should mention this.
What is the necessity of using Application.DoEvents and when we should use it?
Application.DoEvents is usually used to make sure that events get handled periodicaly when you're performing some long-running operation on the UI thread.
A better solution is just not to do that. Perform long-running operations on separate threads, marshalling to the UI thread (either using Control.BeginInvoke/Invoke or with BackgroundWorker) when you need to update the UI.
Application.DoEvents introduces the possibility of re-entrancy, which can lead to very hard-to-understand bugs.
Windows maintains a queue to hold various events like click, resize, close, etc. While a control is responding to an event, all other events are held back in the queue. So if your application is taking unduly long to process a button-click, rest of the application would appear to freeze. Consequently it is possible that your application appears unresponsive while it is doing some heavy processing in response to an event. While you should ideally do heavy processing in an asynchronous manner to ensure that the UI doesn’t freeze, a quick and easy solution is to just call Application.DoEvents() periodically to allow pending events to be sent to your application.
For good windows application, end user doesn’t like when any form of application are freezing out while performing larger/heavyweight operation. User always wants application run smoothly and in responsive manner rather than freezing UI. But after googling i found that Application.DoEvents() is not a good practice to use in application more frequently so instead this events it’s better to use BackGround Worker Thread for performing long running task without freezing windows.
You can get better idea if you practically look it. Just copy following code and check application with and without putting Application.DoEvents().
Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
For i As Integer = 0 To 1000
System.Threading.Thread.Sleep(100)
ListBox1.Items.Add(i.ToString())
Application.DoEvents()
Next
End Sub
Imho you should more less never use it, as you might end up with very unexpected behavior.
Just generated code is ok. Things like you are executing again the event handler you are currently in,because the user pressed a key twice etc etc.
If you want to refresh a control to display the current process you should explicitly call .Update on that control in instead of calling Application.DoEvents.