473,323 Members | 1,550 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,323 software developers and data experts.

STAThread vs non STAThread framework

Hi All,
I have a big problem with STAThread attribute. I'm using XNA framework
connected with WinForms. XNA is working in non STAThread. I have a
problem with displaying CommonDialog forms e.g. OpenFileDialog. I
can't declare a main method as STAThread because of XNA framework. Is
there any way to declare form or some method in form as STAThread (I
think that a method from Form can invoke OpenFileDialog) maybe I'm
wrong.

Do you know how I can resolve a problem?

Thanks.
RK.

Oct 22 '07 #1
12 5018
"rafalK" <kr*******@gmail.comwrote in message
news:11*********************@k35g2000prh.googlegro ups.com...
Hi All,
I have a big problem with STAThread attribute. I'm using XNA framework
connected with WinForms. XNA is working in non STAThread. I have a
problem with displaying CommonDialog forms e.g. OpenFileDialog. I
can't declare a main method as STAThread because of XNA framework. Is
there any way to declare form or some method in form as STAThread (I
think that a method from Form can invoke OpenFileDialog) maybe I'm
wrong.

Do you know how I can resolve a problem?

Thanks.
RK.
A Windows Forms application MUST be tagged with the STAThread attribute, no
way around this.
Not sure what you mean with "XNA is working in non STA Thread" though, do
you mean you are running XNA code in a separate thread, or are you running
XNA code on the main thread?
In the latter case, you simply need to add STAThread to your main entry, in
the first case you'll have to delegate the calls to the form by means of
Control.Invoke/BeginInvoke whenever you need to access the From or one of
it's elements.
Willy.

Oct 22 '07 #2
Willy Denoyette [MVP] <wi*************@telenet.bewrote:

<snip>
A Windows Forms application MUST be tagged with the STAThread
attribute, no way around this.
Out of interest, what are the problems one might find without this? For
test purposes I've often created forms which do very little, and rarely
bothered to put the STAThread attribute on them. They've been fine -
but I quite understand that either this was through chance or because I
wasn't using particular components.

--
Jon Skeet - <sk***@pobox.com>
http://www.pobox.com/~skeet Blog: http://www.msmvps.com/jon.skeet
If replying to the group, please do not mail me too
Oct 22 '07 #3
The only times I've needed it are when:
* using the Clipboard object
* using ActiveX controls / components

Other than that, I have never seen any issues in the wild when
omitting this...

Marc
Oct 22 '07 #4
I'm running XNA code in main thread and also Form is starting from
main thread. I'm working now without STAThread in main entry and it
works. But as I wrote some is not working. XNA (game library) can't
use STAThread declared in main thread because some components will not
work.
Do You know any way to get round problem ?

Oct 22 '07 #5
Use different threads for any code that /must/ be STA, and code that
/must not/ be STA?

Marc
Oct 22 '07 #6
"Jon Skeet [C# MVP]" <sk***@pobox.comwrote in message
news:MP*********************@msnews.microsoft.com. ..
Willy Denoyette [MVP] <wi*************@telenet.bewrote:

<snip>
>A Windows Forms application MUST be tagged with the STAThread
attribute, no way around this.

Out of interest, what are the problems one might find without this? For
test purposes I've often created forms which do very little, and rarely
bothered to put the STAThread attribute on them. They've been fine -
but I quite understand that either this was through chance or because I
wasn't using particular components.

--
Jon Skeet - <sk***@pobox.com>
http://www.pobox.com/~skeet Blog: http://www.msmvps.com/jon.skeet
If replying to the group, please do not mail me too

Jon,

A couple of the Windows Forms controls are simple wrappers around ActiveX
COM controls, notably all the "Dialog Controls" are AX control wrappers, one
of them being the OpenFileDialog as used by the OP.
Such controls need a *pumping* STA thread to run on.
Now, if you don't initialize your UI thread to enter an STA, the CLR will
initialize the thread to enter the MTA whenever you call into COM for the
first time, that is when you create an instance of say OpenFileDialog. Note
that the v2 SP1 CLR initializes the thread to enter the MTA (if not marked
otherwise) even before it starts the main thread.
FileDialog (the wrapped AX dialog) as all other dialogs, is marked as
requiring an STA, so it can't get instantiated on the calling MTA thread,
COM takes care of this by creating a new thread that gets initialized to
enter an STA and creates the instance of the dialog on this thread and
returns a proxy to the caller.
That mean you'll end with the following (important for this discussion)
threads in a Forms application that doesn't mark it's main UI thread as
STAThread.

Main thread (UI) MTA.
GDI Thread MTA (used by Forms)
STA thread created by COM hosting the FileDialog AX control.

So far so good, the control runs on a compatible thread, and the caller
receives a proxy (a marshaled Interface Pointer). The problem however is
that the STA thread created by COM on your behalf isn't pumping messages,
that means that your OpenFileDialog cannot communicate with the callers
thread. The result is that the dialog cannot be used,it will not even
show-up (I guess) and the UI thread deadlocks.
Note also that the Finalizer (MTA) thread cannot access the controls STA
thread whenever he needs to run the Control's Finalize method. This is no
big deal in this scenario, as the control is non-functional anyway, but it's
a big issue when you have to deal with non-visual AX controls.

Willy.
Oct 22 '07 #7
Willy Denoyette [MVP] <wi*************@telenet.bewrote:
Out of interest, what are the problems one might find without this? For
test purposes I've often created forms which do very little, and rarely
bothered to put the STAThread attribute on them. They've been fine -
but I quite understand that either this was through chance or because I
wasn't using particular components.

A couple of the Windows Forms controls are simple wrappers around ActiveX
COM controls, notably all the "Dialog Controls" are AX control wrappers, one
of them being the OpenFileDialog as used by the OP.
Such controls need a *pumping* STA thread to run on.
Right. Okay, so in many cases you'd get away with it not entirely
through chance but just by not using the controls which require the
pumping STA.
Now, if you don't initialize your UI thread to enter an STA, the CLR will
initialize the thread to enter the MTA whenever you call into COM for the
first time, that is when you create an instance of say OpenFileDialog. Note
that the v2 SP1 CLR initializes the thread to enter the MTA (if not marked
otherwise) even before it starts the main thread.
Yikes - that sounds like a significant change. My understanding was
that the CLR would only initialize a thread one way or another the
first time a method with STAThread or MTAThread was encountered on that
thread. In other words, your Main method could call something else
which in turn was decorated with STAThread. Am I right in interpreting
your comments to say this isn't the case with the v2 CLR SP1?
FileDialog (the wrapped AX dialog) as all other dialogs, is marked as
requiring an STA, so it can't get instantiated on the calling MTA thread,
COM takes care of this by creating a new thread that gets initialized to
enter an STA and creates the instance of the dialog on this thread and
returns a proxy to the caller.
That mean you'll end with the following (important for this discussion)
threads in a Forms application that doesn't mark it's main UI thread as
STAThread.

Main thread (UI) MTA.
GDI Thread MTA (used by Forms)
STA thread created by COM hosting the FileDialog AX control.
Why is the GDI thread not the main thread? I thought that
Application.Run just ran the message pump on the current thread? Or
does GDI just need two threads anyway, one for message pumping and one
for something else?
So far so good, the control runs on a compatible thread, and the caller
receives a proxy (a marshaled Interface Pointer). The problem however is
that the STA thread created by COM on your behalf isn't pumping messages,
that means that your OpenFileDialog cannot communicate with the callers
thread. The result is that the dialog cannot be used,it will not even
show-up (I guess) and the UI thread deadlocks.
Note also that the Finalizer (MTA) thread cannot access the controls STA
thread whenever he needs to run the Control's Finalize method. This is no
big deal in this scenario, as the control is non-functional anyway, but it's
a big issue when you have to deal with non-visual AX controls.
Right. Thanks for clearing that up. Admittedly it's open up other cans
of worms in terms of my understanding of WinForms, but there we go...

--
Jon Skeet - <sk***@pobox.com>
http://www.pobox.com/~skeet Blog: http://www.msmvps.com/jon.skeet
If replying to the group, please do not mail me too
Oct 22 '07 #8
"Jon Skeet [C# MVP]" <sk***@pobox.comwrote in message
news:MP*********************@msnews.microsoft.com. ..
Willy Denoyette [MVP] <wi*************@telenet.bewrote:
Out of interest, what are the problems one might find without this? For
test purposes I've often created forms which do very little, and rarely
bothered to put the STAThread attribute on them. They've been fine -
but I quite understand that either this was through chance or because I
wasn't using particular components.

A couple of the Windows Forms controls are simple wrappers around ActiveX
COM controls, notably all the "Dialog Controls" are AX control wrappers,
one
of them being the OpenFileDialog as used by the OP.
Such controls need a *pumping* STA thread to run on.

Right. Okay, so in many cases you'd get away with it not entirely
through chance but just by not using the controls which require the
pumping STA.
If you only use controls that are *not* COM based, *and* If you don't use
"cust and paste" support in Windows Forms, which is OLE based (OLE is a COM
based technology), then you can safely ignore the STAThread attribute on
main, but why would you?
The problem is that you can't possibly know which controls are COM based and
which are not, so STATHread is a safe bet when you have to deal with Forms
and V3's WPF.
>Now, if you don't initialize your UI thread to enter an STA, the CLR will
initialize the thread to enter the MTA whenever you call into COM for the
first time, that is when you create an instance of say OpenFileDialog.
Note
that the v2 SP1 CLR initializes the thread to enter the MTA (if not
marked
otherwise) even before it starts the main thread.

Yikes - that sounds like a significant change. My understanding was
that the CLR would only initialize a thread one way or another the
first time a method with STAThread or MTAThread was encountered on that
thread. In other words, your Main method could call something else
which in turn was decorated with STAThread. Am I right in interpreting
your comments to say this isn't the case with the v2 CLR SP1?
The current version of the CLR initilizes COM at the first call into a RCW,
say from the main UI thread. If the main entry is not tagged with a thread
attribute, the RCW will initialize the thread to enter the MTA, else it will
initialize the thread to enter the apartment that is specified by the
attribute.
The problem with the current version is that initializing at first call
might be too late , therefore the CLR team took the decision to initialize
the thread before calling main. That means that the UI thread is always
initialize when main starts executing, and there is no surprise here,
STAThread initializes the thread to enter an STA, all other cases initialize
the thread to enter the MTA.

>FileDialog (the wrapped AX dialog) as all other dialogs, is marked as
requiring an STA, so it can't get instantiated on the calling MTA thread,
COM takes care of this by creating a new thread that gets initialized to
enter an STA and creates the instance of the dialog on this thread and
returns a proxy to the caller.
That mean you'll end with the following (important for this discussion)
threads in a Forms application that doesn't mark it's main UI thread as
STAThread.

Main thread (UI) MTA.
GDI Thread MTA (used by Forms)
STA thread created by COM hosting the FileDialog AX control.

Why is the GDI thread not the main thread? I thought that
Application.Run just ran the message pump on the current thread? Or
does GDI just need two threads anyway, one for message pumping and one
for something else?
GDI creates and manages it's own thread, this is not a CLR thread , it
becomes a CLR thread when this thread calls back into the main thread.

>So far so good, the control runs on a compatible thread, and the caller
receives a proxy (a marshaled Interface Pointer). The problem however is
that the STA thread created by COM on your behalf isn't pumping messages,
that means that your OpenFileDialog cannot communicate with the callers
thread. The result is that the dialog cannot be used,it will not even
show-up (I guess) and the UI thread deadlocks.
Note also that the Finalizer (MTA) thread cannot access the controls STA
thread whenever he needs to run the Control's Finalize method. This is
no
big deal in this scenario, as the control is non-functional anyway, but
it's
a big issue when you have to deal with non-visual AX controls.

Right. Thanks for clearing that up. Admittedly it's open up other cans
of worms in terms of my understanding of WinForms, but there we go...
Well, I guess it's just a matter of respecting a number of simple rules
(this is in general what Software development is all about), if you don't
then you better know what's going on under the covers.

Willy.

Oct 22 '07 #9
Willy Denoyette [MVP] <wi*************@telenet.bewrote:
Right. Okay, so in many cases you'd get away with it not entirely
through chance but just by not using the controls which require the
pumping STA.

If you only use controls that are *not* COM based, *and* If you don't use
"cust and paste" support in Windows Forms, which is OLE based (OLE is a COM
based technology), then you can safely ignore the STAThread attribute on
main, but why would you?
In my case it's simply been forgetfulness for throwaway apps.
The problem is that you can't possibly know which controls are COM based and
which are not, so STATHread is a safe bet when you have to deal with Forms
and V3's WPF.
Fair enough.
Yikes - that sounds like a significant change. My understanding was
that the CLR would only initialize a thread one way or another the
first time a method with STAThread or MTAThread was encountered on that
thread. In other words, your Main method could call something else
which in turn was decorated with STAThread. Am I right in interpreting
your comments to say this isn't the case with the v2 CLR SP1?

The current version of the CLR initilizes COM at the first call into a RCW,
say from the main UI thread. If the main entry is not tagged with a thread
attribute, the RCW will initialize the thread to enter the MTA, else it will
initialize the thread to enter the apartment that is specified by the
attribute.
The problem with the current version is that initializing at first call
might be too late , therefore the CLR team took the decision to initialize
the thread before calling main. That means that the UI thread is always
initialize when main starts executing, and there is no surprise here,
STAThread initializes the thread to enter an STA, all other cases initialize
the thread to enter the MTA.
Hmm... that still sounds like a breaking change where previously you
might have had:

Main (no attribute) calling...
StartUI (STAThread) calling...
OtherStuff

I *think* that would have previously used an STAThread, but is now
using an MTAThread (and is therefore incorrect). Or am I just wrong
about it previously using an STAThread in that case?
Main thread (UI) MTA.
GDI Thread MTA (used by Forms)
STA thread created by COM hosting the FileDialog AX control.
Why is the GDI thread not the main thread? I thought that
Application.Run just ran the message pump on the current thread? Or
does GDI just need two threads anyway, one for message pumping and one
for something else?

GDI creates and manages it's own thread, this is not a CLR thread , it
becomes a CLR thread when this thread calls back into the main thread.
Blick. Hopefully Joe Duffy's new book will explain all this when it
comes out :) I'm woefully uninformed when it comes to WinForms
threading. General threading principles I'm fine with, but this is
somewhat different.
Right. Thanks for clearing that up. Admittedly it's open up other cans
of worms in terms of my understanding of WinForms, but there we go...

Well, I guess it's just a matter of respecting a number of simple rules
(this is in general what Software development is all about), if you don't
then you better know what's going on under the covers.
True.

--
Jon Skeet - <sk***@pobox.com>
http://www.pobox.com/~skeet Blog: http://www.msmvps.com/jon.skeet
If replying to the group, please do not mail me too
Oct 22 '07 #10
"Jon Skeet [C# MVP]" <sk***@pobox.comwrote in message
news:MP*********************@msnews.microsoft.com. ..
Willy Denoyette [MVP] <wi*************@telenet.bewrote:
Right. Okay, so in many cases you'd get away with it not entirely
through chance but just by not using the controls which require the
pumping STA.

If you only use controls that are *not* COM based, *and* If you don't
use
"cust and paste" support in Windows Forms, which is OLE based (OLE is a
COM
based technology), then you can safely ignore the STAThread attribute on
main, but why would you?

In my case it's simply been forgetfulness for throwaway apps.
No big deal in this case, as long as you keep in mind that in case of a
Forms application, that you are creating at least one additional thread
possibly two, that means 1 or 2MB additional stack space used (4 or 8MB on
X64).

>The problem is that you can't possibly know which controls are COM based
and
which are not, so STATHread is a safe bet when you have to deal with
Forms
and V3's WPF.

Fair enough.
Yikes - that sounds like a significant change. My understanding was
that the CLR would only initialize a thread one way or another the
first time a method with STAThread or MTAThread was encountered on that
thread. In other words, your Main method could call something else
which in turn was decorated with STAThread. Am I right in interpreting
your comments to say this isn't the case with the v2 CLR SP1?

The current version of the CLR initilizes COM at the first call into a
RCW,
say from the main UI thread. If the main entry is not tagged with a
thread
attribute, the RCW will initialize the thread to enter the MTA, else it
will
initialize the thread to enter the apartment that is specified by the
attribute.
The problem with the current version is that initializing at first call
might be too late , therefore the CLR team took the decision to
initialize
the thread before calling main. That means that the UI thread is always
initialize when main starts executing, and there is no surprise here,
STAThread initializes the thread to enter an STA, all other cases
initialize
the thread to enter the MTA.

Hmm... that still sounds like a breaking change where previously you
might have had:

Main (no attribute) calling...
StartUI (STAThread) calling...
OtherStuff

I *think* that would have previously used an STAThread, but is now
using an MTAThread (and is therefore incorrect). Or am I just wrong
about it previously using an STAThread in that case?
I'm afraid you are wrong here , the main thread is "non-initialized" at the
start of an non-attributed Main, such main thread initializes to enter the
MTA whenever some code running in this thread calls into COM.
The only difference is that now(V2 SP1), the main thread will enter an STA
when the attribute is set, else it enters the MTA, *before* calling Main.

>Main thread (UI) MTA.
GDI Thread MTA (used by Forms)
STA thread created by COM hosting the FileDialog AX control.

Why is the GDI thread not the main thread? I thought that
Application.Run just ran the message pump on the current thread? Or
does GDI just need two threads anyway, one for message pumping and one
for something else?

GDI creates and manages it's own thread, this is not a CLR thread , it
becomes a CLR thread when this thread calls back into the main thread.

Blick. Hopefully Joe Duffy's new book will explain all this when it
comes out :) I'm woefully uninformed when it comes to WinForms
threading. General threading principles I'm fine with, but this is
somewhat different.
I don't know whether Joe will talk about this unmanaged GDI++ stuff, note
that Windows Forms has some more (unmanaged) thread magic going on under
the covers, especially when you are calling into OLE stuff or AX controls
(like Dialogs) from a wrong (non STA) thread.

Right. Thanks for clearing that up. Admittedly it's open up other cans
of worms in terms of my understanding of WinForms, but there we go...

Well, I guess it's just a matter of respecting a number of simple rules
(this is in general what Software development is all about), if you don't
then you better know what's going on under the covers.

True.

--
Jon Skeet - <sk***@pobox.com>
http://www.pobox.com/~skeet Blog: http://www.msmvps.com/jon.skeet
If replying to the group, please do not mail me too
Willy.

Oct 22 '07 #11
Willy Denoyette [MVP] <wi*************@telenet.bewrote:

<snip>
Hmm... that still sounds like a breaking change where previously you
might have had:

Main (no attribute) calling...
StartUI (STAThread) calling...
OtherStuff

I *think* that would have previously used an STAThread, but is now
using an MTAThread (and is therefore incorrect). Or am I just wrong
about it previously using an STAThread in that case?
I'm afraid you are wrong here , the main thread is "non-initialized" at the
start of an non-attributed Main, such main thread initializes to enter the
MTA whenever some code running in this thread calls into COM.
The only difference is that now(V2 SP1), the main thread will enter an STA
when the attribute is set, else it enters the MTA, *before* calling Main.
Let me clarify - because I now believe I was wrong, but I may also have
put it badly before :)

I thought it would be uninitialized during Main, but on the call to
StartUI (decorated with the STAThread attribute) it would become
initialized as STA.

Now I've just read in the STAThreadAttribute this bit:

<quote>
Apply this attribute to the entry point method (the Main() method in C#
and Visual Basic). It has no effect on other methods.
</quote>

That proves me wrong pretty categorically. Thanks for being patient
with my ignorance :)
GDI creates and manages it's own thread, this is not a CLR thread , it
becomes a CLR thread when this thread calls back into the main thread.
Blick. Hopefully Joe Duffy's new book will explain all this when it
comes out :) I'm woefully uninformed when it comes to WinForms
threading. General threading principles I'm fine with, but this is
somewhat different.

I don't know whether Joe will talk about this unmanaged GDI++ stuff, note
that Windows Forms has some more (unmanaged) thread magic going on under
the covers, especially when you are calling into OLE stuff or AX controls
(like Dialogs) from a wrong (non STA) thread.
Right. I'd be surprised if he left it out entirely - but we'll have to
see. It's definitely on my "must buy" list.

--
Jon Skeet - <sk***@pobox.com>
http://www.pobox.com/~skeet Blog: http://www.msmvps.com/jon.skeet
If replying to the group, please do not mail me too
Oct 22 '07 #12
"Jon Skeet [C# MVP]" <sk***@pobox.comwrote in message
news:MP*********************@msnews.microsoft.com. ..
Willy Denoyette [MVP] <wi*************@telenet.bewrote:

<snip>
Hmm... that still sounds like a breaking change where previously you
might have had:

Main (no attribute) calling...
StartUI (STAThread) calling...
OtherStuff

I *think* that would have previously used an STAThread, but is now
using an MTAThread (and is therefore incorrect). Or am I just wrong
about it previously using an STAThread in that case?
I'm afraid you are wrong here , the main thread is "non-initialized" at
the
start of an non-attributed Main, such main thread initializes to enter
the
MTA whenever some code running in this thread calls into COM.
The only difference is that now(V2 SP1), the main thread will enter an
STA
when the attribute is set, else it enters the MTA, *before* calling Main.

Let me clarify - because I now believe I was wrong, but I may also have
put it badly before :)
Maybe I wasn't clear when explaining ;-)
I thought it would be uninitialized during Main, but on the call to
StartUI (decorated with the STAThread attribute) it would become
initialized as STA.
A decorated Main (On a pre-SP1) gets initialized (STA or MTA) just before
the CLR calls Main. A non-decorated Main gets MTA initialized by Forms code
(when calling into COM).
On SP1 the CLR initializes the thread quite a bit before calling Main. A
non-decorated Main enters the MTA, a decorated Main gets initialized
depending it's attribute value. In short, on SP1 you are certain that your
Main function is initialized on entry.
Right. I'd be surprised if he left it out entirely - but we'll have to
see. It's definitely on my "must buy" list.
Lets hope it doesn't take that that long or we will have to write something
ourselves :-), anyway I have it on my list too.

Willy.
Oct 22 '07 #13

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

Similar topics

0
by: sonu | last post by:
Hi I have developed a smart client application. When i try to execute it. It displays the first form which is the login screen. On giving the corrent login id and password, the main form opens....
11
by: warren | last post by:
Hello, Anyone can brief me what is this in front of the Main method for? and when must it be there, and when is it optional? thank you.
3
by: Justine | last post by:
hi all, i just want to know the significance of in the C# application. Why & for What reason is this used. Thanz in Advance, Justine
9
by: | last post by:
Hi All, I have allready tried to ask a similar question , but got no answer until now. In the meantime, I found, that I cannot understand some thread-settings for the Main() function . If I use...
1
by: Alberto | last post by:
What's the meaning of the STAThread attribute? Thanks
2
by: Tom | last post by:
Do we need to put the STAThread attribute on our Sub Main anymore if we are using the 1.1 Framework? See some YEAs and NEAs when searching on Google so thought I would ask here. Tom
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...
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
0
by: Faith0G | last post by:
I am starting a new it consulting business and it's been a while since I setup a new website. Is wordpress still the best web based software for hosting a 5 page website? The webpages will be...
0
isladogs
by: isladogs | last post by:
The next Access Europe User Group meeting will be on Wednesday 3 Apr 2024 starting at 18:00 UK time (6PM UTC+1) and finishing by 19:30 (7.30PM). In this session, we are pleased to welcome former...

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.