473,326 Members | 2,173 Online
Bytes | Software Development & Data Engineering Community
Post Job

Home Posts Topics Members FAQ

Join Bytes to post your question to a community of 473,326 software developers and data experts.

ObservableCollection(of T): Only for UI-tier or for all tiers?

Hello!

In some situations I have a collection of objects which it in different
situations could be relevant to deal with at the UI-tier and sometimes at
other tiers. Typically my concept is a composite so MyCollectionElementClass
has a collection of MyCollectionElementClass.

Should I make one implementation for the UI-tier using
ObservableCollection(MyCollectionElementClass) and one for the non-UI tier
using List(MyCollectionElementClass) or should I use the implementation
using ObservableCollection(MyCollectionElementClass) for all tiers?

A more general question: Should ObservableCollection(Of T) basically only be
used at UI-tiers due to some performance or infrastructural reasons for
instance?
Best regards,

Henrik Dahl
Apr 7 '07 #1
8 3050
Henrik,

I don't see why it shouldn't be used at all tiers. ObservableCollection
doesn't have any UI specific functionality. It is basically a Collection<T>
instance which implements INotifyCollectionChanged and
INotifyPropertyChanged. These interfaces, while they can be used for UI,
don't HAVE to be strictly for UI. You might want some code to run when
certain properties are changed (in a chain reaction sort of way). The most
prominent example is UI changes, but not by any means the only example.

Hope this helps.
--
- Nicholas Paldino [.NET/C# MVP]
- mv*@spam.guard.caspershouse.com

"Henrik Dahl" <He********@community.nospamwrote in message
news:uE**************@TK2MSFTNGP06.phx.gbl...
Hello!

In some situations I have a collection of objects which it in different
situations could be relevant to deal with at the UI-tier and sometimes at
other tiers. Typically my concept is a composite so
MyCollectionElementClass has a collection of MyCollectionElementClass.

Should I make one implementation for the UI-tier using
ObservableCollection(MyCollectionElementClass) and one for the non-UI tier
using List(MyCollectionElementClass) or should I use the implementation
using ObservableCollection(MyCollectionElementClass) for all tiers?

A more general question: Should ObservableCollection(Of T) basically only
be used at UI-tiers due to some performance or infrastructural reasons for
instance?
Best regards,

Henrik Dahl


Apr 7 '07 #2
Hello Nicholas,

Yes, but if you invoke some methods from a non-UI thread an exception is
actually raised from the ObservableCollection(Of T) instance. This could
indicate there's something more into this ObservableCollection because what
you've described probably should not lead to such treading related
behaviour. What do you think?
Best regards,

Henrik Dahl

"Nicholas Paldino [.NET/C# MVP]" <mv*@spam.guard.caspershouse.comskrev i
en meddelelse news:e7*************@TK2MSFTNGP06.phx.gbl...
Henrik,

I don't see why it shouldn't be used at all tiers.
ObservableCollection doesn't have any UI specific functionality. It is
basically a Collection<Tinstance which implements
INotifyCollectionChanged and INotifyPropertyChanged. These interfaces,
while they can be used for UI, don't HAVE to be strictly for UI. You
might want some code to run when certain properties are changed (in a
chain reaction sort of way). The most prominent example is UI changes,
but not by any means the only example.

Hope this helps.
--
- Nicholas Paldino [.NET/C# MVP]
- mv*@spam.guard.caspershouse.com

"Henrik Dahl" <He********@community.nospamwrote in message
news:uE**************@TK2MSFTNGP06.phx.gbl...
>Hello!

In some situations I have a collection of objects which it in different
situations could be relevant to deal with at the UI-tier and sometimes at
other tiers. Typically my concept is a composite so
MyCollectionElementClass has a collection of MyCollectionElementClass.

Should I make one implementation for the UI-tier using
ObservableCollection(MyCollectionElementClass) and one for the non-UI
tier using List(MyCollectionElementClass) or should I use the
implementation using ObservableCollection(MyCollectionElementClass) for
all tiers?

A more general question: Should ObservableCollection(Of T) basically only
be used at UI-tiers due to some performance or infrastructural reasons
for instance?
Best regards,

Henrik Dahl



Apr 7 '07 #3
Henrik,

That isn't the case. There is nothing in ObservableCollection which is
tied to the UI. The error is expected, as you are trying to update the UI
thread from a non UI thread (something not allowed in WPF as well as Win32).
--
- Nicholas Paldino [.NET/C# MVP]
- mv*@spam.guard.caspershouse.com

"Henrik Dahl" <He********@community.nospamwrote in message
news:uz**************@TK2MSFTNGP03.phx.gbl...
Hello Nicholas,

Yes, but if you invoke some methods from a non-UI thread an exception is
actually raised from the ObservableCollection(Of T) instance. This could
indicate there's something more into this ObservableCollection because
what you've described probably should not lead to such treading related
behaviour. What do you think?
Best regards,

Henrik Dahl

"Nicholas Paldino [.NET/C# MVP]" <mv*@spam.guard.caspershouse.comskrev i
en meddelelse news:e7*************@TK2MSFTNGP06.phx.gbl...
>Henrik,

I don't see why it shouldn't be used at all tiers.
ObservableCollection doesn't have any UI specific functionality. It is
basically a Collection<Tinstance which implements
INotifyCollectionChanged and INotifyPropertyChanged. These interfaces,
while they can be used for UI, don't HAVE to be strictly for UI. You
might want some code to run when certain properties are changed (in a
chain reaction sort of way). The most prominent example is UI changes,
but not by any means the only example.

Hope this helps.
--
- Nicholas Paldino [.NET/C# MVP]
- mv*@spam.guard.caspershouse.com

"Henrik Dahl" <He********@community.nospamwrote in message
news:uE**************@TK2MSFTNGP06.phx.gbl...
>>Hello!

In some situations I have a collection of objects which it in different
situations could be relevant to deal with at the UI-tier and sometimes
at other tiers. Typically my concept is a composite so
MyCollectionElementClass has a collection of MyCollectionElementClass.

Should I make one implementation for the UI-tier using
ObservableCollection(MyCollectionElementClass) and one for the non-UI
tier using List(MyCollectionElementClass) or should I use the
implementation using ObservableCollection(MyCollectionElementClass) for
all tiers?

A more general question: Should ObservableCollection(Of T) basically
only be used at UI-tiers due to some performance or infrastructural
reasons for instance?
Best regards,

Henrik Dahl




Apr 7 '07 #4
Hello again!

OK, so your point is, that the exception is not thrown by
ObservableCollection(Of T) but by some action performed by an event handler
erroneously invoked by the non-UI thread in this case?
Best regards,

Henrik Dahl

"Nicholas Paldino [.NET/C# MVP]" <mv*@spam.guard.caspershouse.comskrev i
en meddelelse news:eC*************@TK2MSFTNGP06.phx.gbl...
Henrik,

That isn't the case. There is nothing in ObservableCollection which is
tied to the UI. The error is expected, as you are trying to update the UI
thread from a non UI thread (something not allowed in WPF as well as
Win32).
--
- Nicholas Paldino [.NET/C# MVP]
- mv*@spam.guard.caspershouse.com

"Henrik Dahl" <He********@community.nospamwrote in message
news:uz**************@TK2MSFTNGP03.phx.gbl...
>Hello Nicholas,

Yes, but if you invoke some methods from a non-UI thread an exception is
actually raised from the ObservableCollection(Of T) instance. This could
indicate there's something more into this ObservableCollection because
what you've described probably should not lead to such treading related
behaviour. What do you think?
Best regards,

Henrik Dahl

"Nicholas Paldino [.NET/C# MVP]" <mv*@spam.guard.caspershouse.comskrev
i en meddelelse news:e7*************@TK2MSFTNGP06.phx.gbl...
>>Henrik,

I don't see why it shouldn't be used at all tiers.
ObservableCollection doesn't have any UI specific functionality. It is
basically a Collection<Tinstance which implements
INotifyCollectionChanged and INotifyPropertyChanged. These interfaces,
while they can be used for UI, don't HAVE to be strictly for UI. You
might want some code to run when certain properties are changed (in a
chain reaction sort of way). The most prominent example is UI changes,
but not by any means the only example.

Hope this helps.
--
- Nicholas Paldino [.NET/C# MVP]
- mv*@spam.guard.caspershouse.com

"Henrik Dahl" <He********@community.nospamwrote in message
news:uE**************@TK2MSFTNGP06.phx.gbl...
Hello!

In some situations I have a collection of objects which it in different
situations could be relevant to deal with at the UI-tier and sometimes
at other tiers. Typically my concept is a composite so
MyCollectionElementClass has a collection of MyCollectionElementClass.

Should I make one implementation for the UI-tier using
ObservableCollection(MyCollectionElementClass ) and one for the non-UI
tier using List(MyCollectionElementClass) or should I use the
implementation using ObservableCollection(MyCollectionElementClass) for
all tiers?

A more general question: Should ObservableCollection(Of T) basically
only be used at UI-tiers due to some performance or infrastructural
reasons for instance?
Best regards,

Henrik Dahl




Apr 7 '07 #5
Henrik,

Yes.
--
- Nicholas Paldino [.NET/C# MVP]
- mv*@spam.guard.caspershouse.com

"Henrik Dahl" <He********@community.nospamwrote in message
news:eC**************@TK2MSFTNGP04.phx.gbl...
Hello again!

OK, so your point is, that the exception is not thrown by
ObservableCollection(Of T) but by some action performed by an event
handler erroneously invoked by the non-UI thread in this case?
Best regards,

Henrik Dahl

"Nicholas Paldino [.NET/C# MVP]" <mv*@spam.guard.caspershouse.comskrev i
en meddelelse news:eC*************@TK2MSFTNGP06.phx.gbl...
>Henrik,

That isn't the case. There is nothing in ObservableCollection which
is tied to the UI. The error is expected, as you are trying to update
the UI thread from a non UI thread (something not allowed in WPF as well
as Win32).
--
- Nicholas Paldino [.NET/C# MVP]
- mv*@spam.guard.caspershouse.com

"Henrik Dahl" <He********@community.nospamwrote in message
news:uz**************@TK2MSFTNGP03.phx.gbl...
>>Hello Nicholas,

Yes, but if you invoke some methods from a non-UI thread an exception is
actually raised from the ObservableCollection(Of T) instance. This could
indicate there's something more into this ObservableCollection because
what you've described probably should not lead to such treading related
behaviour. What do you think?
Best regards,

Henrik Dahl

"Nicholas Paldino [.NET/C# MVP]" <mv*@spam.guard.caspershouse.comskrev
i en meddelelse news:e7*************@TK2MSFTNGP06.phx.gbl...
Henrik,

I don't see why it shouldn't be used at all tiers.
ObservableCollection doesn't have any UI specific functionality. It is
basically a Collection<Tinstance which implements
INotifyCollectionChanged and INotifyPropertyChanged. These interfaces,
while they can be used for UI, don't HAVE to be strictly for UI. You
might want some code to run when certain properties are changed (in a
chain reaction sort of way). The most prominent example is UI changes,
but not by any means the only example.

Hope this helps.
--
- Nicholas Paldino [.NET/C# MVP]
- mv*@spam.guard.caspershouse.com

"Henrik Dahl" <He********@community.nospamwrote in message
news:uE**************@TK2MSFTNGP06.phx.gbl...
Hello!
>
In some situations I have a collection of objects which it in
different situations could be relevant to deal with at the UI-tier and
sometimes at other tiers. Typically my concept is a composite so
MyCollectionElementClass has a collection of MyCollectionElementClass.
>
Should I make one implementation for the UI-tier using
ObservableCollection(MyCollectionElementClas s) and one for the non-UI
tier using List(MyCollectionElementClass) or should I use the
implementation using ObservableCollection(MyCollectionElementClass)
for all tiers?
>
A more general question: Should ObservableCollection(Of T) basically
only be used at UI-tiers due to some performance or infrastructural
reasons for instance?
>
>
Best regards,
>
Henrik Dahl
>
>




Apr 7 '07 #6
OK.

Do you know if instances of ObservableCollection(Of T) may also be
marshalled via the serialization mechanishms of WCF or via XmlSerializer?
Best regards,

Henrik Dahl

"Nicholas Paldino [.NET/C# MVP]" <mv*@spam.guard.caspershouse.comskrev i
en meddelelse news:%2****************@TK2MSFTNGP02.phx.gbl...
Henrik,

Yes.
--
- Nicholas Paldino [.NET/C# MVP]
- mv*@spam.guard.caspershouse.com

"Henrik Dahl" <He********@community.nospamwrote in message
news:eC**************@TK2MSFTNGP04.phx.gbl...
>Hello again!

OK, so your point is, that the exception is not thrown by
ObservableCollection(Of T) but by some action performed by an event
handler erroneously invoked by the non-UI thread in this case?
Best regards,

Henrik Dahl

"Nicholas Paldino [.NET/C# MVP]" <mv*@spam.guard.caspershouse.comskrev
i en meddelelse news:eC*************@TK2MSFTNGP06.phx.gbl...
>>Henrik,

That isn't the case. There is nothing in ObservableCollection which
is tied to the UI. The error is expected, as you are trying to update
the UI thread from a non UI thread (something not allowed in WPF as well
as Win32).
--
- Nicholas Paldino [.NET/C# MVP]
- mv*@spam.guard.caspershouse.com

"Henrik Dahl" <He********@community.nospamwrote in message
news:uz**************@TK2MSFTNGP03.phx.gbl...
Hello Nicholas,

Yes, but if you invoke some methods from a non-UI thread an exception
is actually raised from the ObservableCollection(Of T) instance. This
could indicate there's something more into this ObservableCollection
because what you've described probably should not lead to such treading
related behaviour. What do you think?
Best regards,

Henrik Dahl

"Nicholas Paldino [.NET/C# MVP]" <mv*@spam.guard.caspershouse.com>
skrev i en meddelelse news:e7*************@TK2MSFTNGP06.phx.gbl...
Henrik,
>
I don't see why it shouldn't be used at all tiers.
ObservableCollection doesn't have any UI specific functionality. It
is basically a Collection<Tinstance which implements
INotifyCollectionChanged and INotifyPropertyChanged. These
interfaces, while they can be used for UI, don't HAVE to be strictly
for UI. You might want some code to run when certain properties are
changed (in a chain reaction sort of way). The most prominent example
is UI changes, but not by any means the only example.
>
Hope this helps.
>
>
--
- Nicholas Paldino [.NET/C# MVP]
- mv*@spam.guard.caspershouse.com
>
"Henrik Dahl" <He********@community.nospamwrote in message
news:uE**************@TK2MSFTNGP06.phx.gbl.. .
>Hello!
>>
>In some situations I have a collection of objects which it in
>different situations could be relevant to deal with at the UI-tier
>and sometimes at other tiers. Typically my concept is a composite so
>MyCollectionElementClass has a collection of
>MyCollectionElementClass.
>>
>Should I make one implementation for the UI-tier using
>ObservableCollection(MyCollectionElementClass ) and one for the non-UI
>tier using List(MyCollectionElementClass) or should I use the
>implementation using ObservableCollection(MyCollectionElementClass)
>for all tiers?
>>
>A more general question: Should ObservableCollection(Of T) basically
>only be used at UI-tiers due to some performance or infrastructural
>reasons for instance?
>>
>>
>Best regards,
>>
>Henrik Dahl
>>
>>
>
>




Apr 7 '07 #7
Henrik,

Well, did you check the documentation? *smiles*

It says that the Serializable attribute is applied to it, which means
that instances of it can be serialized, assuming that T is serializable.
--
- Nicholas Paldino [.NET/C# MVP]
- mv*@spam.guard.caspershouse.com

"Henrik Dahl" <He********@community.nospamwrote in message
news:OI**************@TK2MSFTNGP05.phx.gbl...
OK.

Do you know if instances of ObservableCollection(Of T) may also be
marshalled via the serialization mechanishms of WCF or via XmlSerializer?
Best regards,

Henrik Dahl

"Nicholas Paldino [.NET/C# MVP]" <mv*@spam.guard.caspershouse.comskrev i
en meddelelse news:%2****************@TK2MSFTNGP02.phx.gbl...
>Henrik,

Yes.
--
- Nicholas Paldino [.NET/C# MVP]
- mv*@spam.guard.caspershouse.com

"Henrik Dahl" <He********@community.nospamwrote in message
news:eC**************@TK2MSFTNGP04.phx.gbl...
>>Hello again!

OK, so your point is, that the exception is not thrown by
ObservableCollection(Of T) but by some action performed by an event
handler erroneously invoked by the non-UI thread in this case?
Best regards,

Henrik Dahl

"Nicholas Paldino [.NET/C# MVP]" <mv*@spam.guard.caspershouse.comskrev
i en meddelelse news:eC*************@TK2MSFTNGP06.phx.gbl...
Henrik,

That isn't the case. There is nothing in ObservableCollection which
is tied to the UI. The error is expected, as you are trying to update
the UI thread from a non UI thread (something not allowed in WPF as
well as Win32).
--
- Nicholas Paldino [.NET/C# MVP]
- mv*@spam.guard.caspershouse.com

"Henrik Dahl" <He********@community.nospamwrote in message
news:uz**************@TK2MSFTNGP03.phx.gbl...
Hello Nicholas,
>
Yes, but if you invoke some methods from a non-UI thread an exception
is actually raised from the ObservableCollection(Of T) instance. This
could indicate there's something more into this ObservableCollection
because what you've described probably should not lead to such
treading related behaviour. What do you think?
>
>
Best regards,
>
Henrik Dahl
>
"Nicholas Paldino [.NET/C# MVP]" <mv*@spam.guard.caspershouse.com>
skrev i en meddelelse news:e7*************@TK2MSFTNGP06.phx.gbl...
>Henrik,
>>
> I don't see why it shouldn't be used at all tiers.
>ObservableCollection doesn't have any UI specific functionality. It
>is basically a Collection<Tinstance which implements
>INotifyCollectionChanged and INotifyPropertyChanged. These
>interfaces, while they can be used for UI, don't HAVE to be strictly
>for UI. You might want some code to run when certain properties are
>changed (in a chain reaction sort of way). The most prominent
>example is UI changes, but not by any means the only example.
>>
> Hope this helps.
>>
>>
>--
> - Nicholas Paldino [.NET/C# MVP]
> - mv*@spam.guard.caspershouse.com
>>
>"Henrik Dahl" <He********@community.nospamwrote in message
>news:uE**************@TK2MSFTNGP06.phx.gbl. ..
>>Hello!
>>>
>>In some situations I have a collection of objects which it in
>>different situations could be relevant to deal with at the UI-tier
>>and sometimes at other tiers. Typically my concept is a composite so
>>MyCollectionElementClass has a collection of
>>MyCollectionElementClass.
>>>
>>Should I make one implementation for the UI-tier using
>>ObservableCollection(MyCollectionElementClas s) and one for the
>>non-UI tier using List(MyCollectionElementClass) or should I use the
>>implementation using ObservableCollection(MyCollectionElementClass)
>>for all tiers?
>>>
>>A more general question: Should ObservableCollection(Of T) basically
>>only be used at UI-tiers due to some performance or infrastructural
>>reasons for instance?
>>>
>>>
>>Best regards,
>>>
>>Henrik Dahl
>>>
>>>
>>
>>
>
>




Apr 8 '07 #8
Hi Henrik,

I agree that ObservableCollection(Of T) can be used for all tiers.
the exception is not thrown by ObservableCollection(Of T) but by some
action performed by an event handler erroneously invoked by the non-UI
thread in this case?

In my opinion, because the ObservableCollection(Of T) implements the
INotifyCollectionChanged and INotifyPropertyChanged interfaces, it will
cause UI update when the ObservableCollection(Of T) is changed.

Let's say a non-UI thread accesses and changes the ObservableCollection(Of
T), then it is the non-UI thread that performs the UI update in the next
step, which is not allowed in the thread models of both WinForms and WPF
applications.

In WinForms world, the solution is to define a delegate for the method to
access the control, and then call the Invoke or BeginInvoke method of the
WinForms control to invoke the delegate.

In WPF world, the solution is similar but is a little different. We still
need to define a delegate for the method to access the UI element, and then
call the Invoke or BeginInvoke method of the Dispather linked to the UI
thread.

The following is a sample.

delegate void SetTextBoxDelegate();
Dispatcher.Invoke(System.Windows.Threading.Dispatc herPriority.Normal, new
SetTextBoxDelegate(SetTextBox1));
void SetTextBox1()
{
this.textBox1.Text = "some text";
}

For more information on the threading model in WPF, you may visit the
following link:

'Threading Model'
http://msdn2.microsoft.com/en-us/library/ms741870.aspx

Hope this helps.
If you have any question, please feel free to let me know.
Sincerely,
Linda Liu
Microsoft Online Community Support

==================================================
Get notification to my posts through email? Please refer to
http://msdn.microsoft.com/subscripti...ult.aspx#notif
ications.

Note: The MSDN Managed Newsgroup support offering is for non-urgent issues
where an initial response from the community or a Microsoft Support
Engineer within 1 business day is acceptable. Please note that each follow
up response may take approximately 2 business days as the support
professional working with you may need further investigation to reach the
most efficient resolution. The offering is not appropriate for situations
that require urgent, real-time or phone-based interactions or complex
project analysis and dump analysis issues. Issues of this nature are best
handled working with a dedicated Microsoft Support Engineer by contacting
Microsoft Customer Support Services (CSS) at
http://msdn.microsoft.com/subscripti...t/default.aspx.
==================================================

This posting is provided "AS IS" with no warranties, and confers no rights.

Apr 9 '07 #9

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

2
by: swoozie | last post by:
This may not be a MSSQL-specific question, but I wanted to ask it here first, in case there's a MSSQL and/or SourceSafe solution that will help. Our dev team is having some difficulty with...
2
by: TS | last post by:
If I have custom data entity objects that are simple classes with properties storing data for a particular entity, then I want to pass this object to another server, how does the other server know...
1
by: ken | last post by:
Dear all does any recommend books for develop middle tiers for .ne recently, i develop asp.net only aspx/dll, database , two tier and vb.net only frm/dll, database, two tiers
1
by: Rupert | last post by:
I am developing a system in ASP.NET and am new to the technology. I am running everything on the laptop I am developing on (windows xp). The DB is Oracle and my aspx pages and C# code behind...
1
by: Freaky Coder | last post by:
Can anyone tell me if I'm insane or not? I have a problem where I have a data tier where every class represents a table, and a class can have properties which are object of another class. For...
5
by: Ronald S. Cook | last post by:
We have a Windows app which contains UI code and all classes that perform business logic and make calls to database stored procs (located on a database server - i.e. not local to the app). My...
5
by: runtime | last post by:
Hello! First time posting... Question about the difference between layers and tiers: How many tiers are in the WAMP environment? This is not an exam question, but the answer will help me...
0
by: jehugaleahsa | last post by:
On Jun 13, 3:09 pm, "Bob Powell " <b...@spamkillerbobpowell.net> wrote: I apologize for the size. I should have probably put this on a blog or something. I'm not interested in tools. I...
10
Samishii23
by: Samishii23 | last post by:
Ok so, I'm trying to make an .exe version of a World of Warcraft system. The Talent builder. I'm hoping that no one points and laughs too much... But anyways, this is the problem I'm having... ...
0
by: ryjfgjl | last post by:
ExcelToDatabase: batch import excel into database automatically...
0
isladogs
by: isladogs | last post by:
The next Access Europe meeting will be on Wednesday 6 Mar 2024 starting at 18:00 UK time (6PM UTC) and finishing at about 19:15 (7.15PM). In this month's session, we are pleased to welcome back...
1
isladogs
by: isladogs | last post by:
The next Access Europe meeting will be on Wednesday 6 Mar 2024 starting at 18:00 UK time (6PM UTC) and finishing at about 19:15 (7.15PM). In this month's session, we are pleased to welcome back...
0
by: jfyes | last post by:
As a hardware engineer, after seeing that CEIWEI recently released a new tool for Modbus RTU Over TCP/UDP filtering and monitoring, I actively went to its official website to take a look. It turned...
0
by: ArrayDB | last post by:
The error message I've encountered is; ERROR:root:Error generating model response: exception: access violation writing 0x0000000000005140, which seems to be indicative of an access violation...
1
by: PapaRatzi | last post by:
Hello, I am teaching myself MS Access forms design and Visual Basic. I've created a table to capture a list of Top 30 singles and forms to capture new entries. The final step is a form (unbound)...
1
by: CloudSolutions | last post by:
Introduction: For many beginners and individual users, requiring a credit card and email registration may pose a barrier when starting to use cloud servers. However, some cloud server providers now...
1
by: Defcon1945 | last post by:
I'm trying to learn Python using Pycharm but import shutil doesn't work
0
by: af34tf | last post by:
Hi Guys, I have a domain whose name is BytesLimited.com, and I want to sell it. Does anyone know about platforms that allow me to list my domain in auction for free. Thank you

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.