0

I am writing a desktop app using SWT which receive log data from network at high speed rate (nearly 100 packet per second). Each packet contains a line which must be appended to a StyledText. Since I receive packets in non-UI thread, I have to use this code:

    display.asyncExec(new Runnable() {

        @Override
        public void run() {
            txtLog.append(log);
            txtLog.setTopIndex(txtLog.getLineCount() - 1);
        }
    });

But this code makes my Logger too slow, and the output of my logger is not synchronized with sender. For example I stop sender device and my program log output stops after 3 minutes!!, However, the eclipse console output( System.out.println() ) is completely sync with sender and stop outputs on time! How does eclipse setText() its StyledText?

stakx - no longer contributing
  • 83,039
  • 20
  • 168
  • 268
MHM
  • 854
  • 1
  • 9
  • 17

1 Answers1

2

Two things:

Use asyncExec rather than syncExec - this will make your logger fast by itself. But if the logger entries are added faster than the UI thread can handle, then the event queue will just become bigger and bigger... and you will have the same slow response as you outlined...

All changes to a StyledText - including appending to it - are rather expensive. Therefore you might also want a middle buffer between your logger and the StyledText widget:

  • the logger adds to the buffer
  • if the buffer was empty, then do an asyncExec
  • the asyncExec Runnable will append the current buffer content and empty the buffer

This works very well in one of my applications...

Tonny Madsen
  • 12,628
  • 4
  • 31
  • 70
  • Thanks for your reply. I was disappointed from this post, until I logged in today. about `asyncExec()` you are right. Actually I used this method in my code instead of `syncExec()`. I was wrong in typing here. Before you answer this question I used some buffering in my app, and the log text is synchronized with sender (50fps), but task manager shows 16% CPU usage permanently for my app. How could I solve it?! – MHM Apr 19 '13 at 02:19
  • "the log text is synchronized with sender(50fps)"?? – Tonny Madsen Apr 19 '13 at 11:16
  • I mean after buffering, I use a scheduler to run `asyncExec()` each 20 milliseconds (50 fps), and append the buffer to widget. But the reuslt is a Huge CPU usage! – MHM Apr 19 '13 at 14:10
  • You might want to look at `Display.timerExec(...)` as an alternative - this will combine the scheduler and `Display.asyncExec(...)` into one. Why 50 fps? 10 fps would be more than enough for a UI usability point-of-view. The high CPU can be from `StyledText` as this _draws_ the text! – Tonny Madsen Apr 20 '13 at 06:53
  • OK, Thanks. I use 50 fps rate because I have to update a canvas as well. but you are right, I must use a lower rate. – MHM Apr 20 '13 at 11:06
  • I would think the CPU usage is almost directly proportional with the update rate :-) – Tonny Madsen Apr 20 '13 at 17:58
  • One more question: What you have done in your app for the time that the text content of `StyledText` became huge?! Do you simply use `getText()` and remove first lines and then use `setText()`? Or there is a better and more efficient way? – MHM Apr 20 '13 at 19:41
  • `StyledText.getContent()` returns a `DefaultContent` and this class have all sorts of methods to make it easy to manipulate the text content itself. – Tonny Madsen Apr 21 '13 at 17:43