Best practice to display data received through event from external source.

R

Rajat

Hi,

I am receiving objects in form of eventArguments through very frequent
events from some external source. Better to say that we need to handle the
flood of events, and process the object received from each event as soon as
possible and wait for the new events.

Right now I keep on adding the received objects in some Arraylist. I need to
use the saved objects for calculation as well as for displaying on UI. I
have used some of the following techniques to complete the job. Can I get
comments or comparison among the points given below for increasing the
performance. Any further improvements/suggestions are most welcome.

1) Use of the Generic List and Dictionary instead of ArrayList
2) Keep on adding the objects in an arraylist till a certain time limit
(lets say 250 ms) and then forward the ArrayList through event to UI/class
for display/calculation. Since shared arraylist acess can create
issues(for filling data from events and fetching data to send), so I can use
the following alernative methods ...
a) Create 2 Arraylists. Fill first arraylist till a certain time
limit, then set a bool variable and start filling alternate arraylist.
Using the first arraylist for sending event to own UI and
then clear this first arraylist. Next do same thing with alternate arraylist
b) Whenever a time limit elaspes, use lock to access a arraylist
and create clone. Use this clone for sending into the eventarg.
3) Firing so many events can bring down the system. So receive the data
in some event from external source and keep adding into arraylist. External
UI etc can fetch the data after certain interval by accessing a
property wrapped arround a cache.

Regards,
Rajat.
 
S

Stoitcho Goutsev \(100\)

Rajat,

Here are my 2 cents:

First I want to say that whatever the case keep in mind that the receivier
and the data processor needs to run in separate threads other wise the
receiver will have to wait for the data processor to finish its work
Further more probably these threads needs to be different than the UI thread
otherwise they will make the UI sluggish. To update the UI in this case will
require marshaling calls to the UI thread which make hurt the performance of
the processing part.
1) Use of the Generic List and Dictionary instead of ArrayList

If the objects are struc ( value types ) by all means use generic
collections (or arrays) to save some to boxing/unboxing and copy operations.
If the objects are reference types and you use ArrayList you will need to do
typecasting, but this is not big of a deal I guess, but eys you can avoid
this using generic collection.
2) Keep on adding the objects in an arraylist till a certain time
limit (lets say 250 ms) and then forward the ArrayList through event to
UI/class for display/calculation. Since shared arraylist acess
can create issues(for filling data from events and fetching data to send),
so I can use the following alernative methods ...

Yes using the same array list is probably not the best idea in this case
because you need to have some sync mechanism in place. Unless you don't
implement some kind of partial locking, which is not going to be the easiest
to do you are not going to gain any performance boost since the receiving
part needs to wait for the calculation machanism.
Probably you can lock the collection only for the duration of fetching an
element from the calculation algorithm
a) Create 2 Arraylists. Fill first arraylist till a certain time
limit, then set a bool variable and start filling alternate arraylist.
Using the first arraylist for sending event to own UI and then clear this
first arraylist. Next do same thing with alternate arraylist

What will hapen if the events comes faster than the calculation algorithm
can process them? In this case you may run in a situation that the second
array is filled out and the first one is not processed yet.

Better you have a queue of collections of data. When the receiving part is
done with this portion of data it adds the prepared collection to tail of
the queue then creates a new one and starts filling it. When the processing
part is done with the current collection it gets a new one by removing it
from the head of the queue and start processing the new one. The old
collections is left for garbage collection. This way you need to lock the
queue only for the duration of the adding and removing.
b) Whenever a time limit elaspes, use lock to access a arraylist
and create clone. Use this clone for sending into the eventarg.

This has again problem with the speed of recieving data and processing them.
3) Firing so many events can bring down the system. So receive the data
in some event from external source and keep adding into arraylist.
External UI etc can fetch the data after certain interval by
accessing a property wrapped arround a cache.


I don't think you shoud worry about performance of events as long as you
have only one handler.

Whatever the case keep in mind that the receivier and the data processor
needs to run in separate threads other wise the receiver will have to wait
for the data processor to finish its work.
 
R

Rajat

Stoitcho,

Thank you for stepwise response. I need to discuss some of the points, which
you have raised...

1) I have taken the Alternative arraylist, as the time elapses I send the
"Arraylist.Values" in case of alternative arraylist approach. So here values
are being passed in the event rather than the reference . At the calculation
end, I reconstruct the ArrayList (using ICollection interface) and then
perform the calculations. Since calculation algos are working on the copies
of objects, hence even if events come faster, we are safe. In case of clone,
again we have a deep copy, so working on this copy should not interfere with
the original copy's processing(Receiving and adding in collection). Do you
still think that applying the queue here can help us?

2) I agree that we need to shift as much job possible on new thread. Here I
need to tell you that we have wired up the events on a "COM control".
Through these events we are getting the external data. I have dragged the
COM control on the form (Data receiver class). Thus I think, I am bounded to
receive the data on the UI thread. Once I tried to send the exact received
object in a new thread and fetch data in new thread itself, I got garbage
data. Am I thinking here in the right direction?

Regards,
Rajat.
 
S

Stoitcho Goutsev \(100\)

Rajat,
1) I have taken the Alternative arraylist, as the time elapses I send the
"Arraylist.Values" in case of alternative arraylist approach. So here
values are being passed in the event rather than the reference . At the
calculation end, I reconstruct the ArrayList (using ICollection interface)
and then perform the calculations. Since calculation algos are working on
the copies of objects, hence even if events come faster, we are safe. In
case of clone, again we have a deep copy, so working on this copy should
not interfere with the original copy's processing(Receiving and adding in
collection). Do you still think that applying the queue here can help us?

What the queue was trying to solve is scenarios where calculations are
slower than receiving data. What will happen in your alternative array if
the array in the receiving part is filled out ant the processing part is not
done with the old data? If the reveiver keeps adding the objects to the
exisiting array list that will prbably solve the problem but the chunks of
work that the processing part must do next time will be bigger and will keep
growing. However the situations won't be much different with the queue
either - the data still needs to be processed. One advantages of the queue
is the it doesn't need to do deep copies of the objects.

2) I agree that we need to shift as much job possible on new thread. Here
I need to tell you that we have wired up the events on a "COM control".
Through these events we are getting the external data. I have dragged the
COM control on the form (Data receiver class). Thus I think, I am bounded
to receive the data on the UI thread. Once I tried to send the exact
received object in a new thread and fetch data in new thread itself, I got
garbage data. Am I thinking here in the right direction?

Windows forms uses Single Thread Apartment model, so yes the events will
come in the UI thread. What you can do is to run separate UI thread for the
COM control and receive the data there and then build your multithread
application using proper sync.
 
R

Rajat

Stoitcho,

I got your point. I will check the comparative performance by applying the a
thread safe queue. Also I am looking forward to
receive the data of COM control events on separate thread at my end. If you
have any handy article dealing with the similar
situation (receive the data of COM control events on separate thread),
please share.

Thanks a lot for wonderful suggestions.

Regards,
Rajat.
 
S

Stoitcho Goutsev \(100\)

Rajat,

I don't have any article, but here you start new UI thread:


Thread t = new Thread( new ThreadStart(ThreadProc));
t.SetApartmentState(ApartmentState.STA);
t.Start();

and the minmum code needed to make a thread to be a UI thread is

void ThreadProc()
{
Application.Run();
}

Depending on the COM object I guess you may need to have a hosting form.
Since win2k there is a support for message-only-windows. Such windows can be
created in WindowsForms using the NativeWindow class, but I don't think this
is going to help in your case. Anyhow if need a form you can create on
hidden form just to host your COM object

void ThreadProc()
{
Form f = new Form();
f.ShowInTaskbar = false;
f.WindowState = FormWindowState.Minimized;
Application.Run(f);
}

Here I use minimized form that doesn't show in the taskbar just because it
is easier than setting the Visible property. When the form starts the
Visible is automatically set to *true* thus simple setting the property
won't work. If you do it in some other place in the form you risk the form
to show-up for a split of a second before disappear. I believe this is
easier to do hidden form.

One more thing... The thread created this way is not a background thread
that is it will keep the application alive unless something kills the
thread. The correct way of doing it is to call the form's Close method.
Other possible solution would be to make the thread a background one, but in
this case it will be kill in a very "brutal" way. The form will be disposed,
but it won't return close notifications.


--
HTH
Stoitcho Goutsev (100)

Rajat said:
Stoitcho,

I got your point. I will check the comparative performance by applying the
a thread safe queue. Also I am looking forward to
receive the data of COM control events on separate thread at my end. If
you have any handy article dealing with the similar
situation (receive the data of COM control events on separate thread),
please share.

Thanks a lot for wonderful suggestions.

Regards,
Rajat.
 
R

Rajat

Right now, I have 2 forms, each hosting a different COM control and getting
the data in form of different events from different servers. I have made the
form classes singleton. These form classes are grouped in a class library
project. I take the instance of these classes and call methods corresponding
to which I start getting data in form of events on the form. So form are not
shown.

Since the instances are made through a GetInstance() method in the same form
class itself, so to apply what you have said, I think I can code this
scenario as ...

TypeName _typeName = null;
public static TypeName GetInstance()
{
if(_typeName == null)
{
Thread t = new Thread( new ThreadStart(ThreadProc));
t.SetApartmentState(ApartmentState.STA);
t.Start();
}

return _typeName;
}

void ThreadProc()
{
f = new _typeName();
Application.Run(f);
}

Is it ok? If Application.Run displays the form then I can definitely use
f.WindowState = FormWindowState.Minimized.

Regards,
Rajat.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Top