473,687 Members | 3,760 Online
Bytes | Software Development & Data Engineering Community
+ Post

Home Posts Topics Members FAQ

Multi-threading article finally "finished" - reviewers welcome

Please excuse the cross-post - I'm pretty sure I've had interest in the
article on all the groups this is posted to.

I've finally managed to finish my article on multi-threading - at least
for the moment. I'd be *very* grateful if people with any interest in
multi-threading would read it (even just bits of it - it's somewhat
long to go through the whole thing!) to check for accuracy,
effectiveness of examples, etc.

Feel free to mail me directly with comments or post them here.

The article is at:
http://www.pobox.com/~skeet/csharp/multithreading.html

--
Jon Skeet - <sk***@pobox.co m>
http://www.pobox.com/~skeet
If replying to the group, please do not mail me too
Jul 21 '05 #1
77 5269
"Jon Skeet [C# MVP]" wrote:

I've finally managed to finish my article on multi-threading - at least
for the moment. I'd be *very* grateful if people with any interest in
multi-threading would read it (even just bits of it - it's somewhat
long to go through the whole thing!) to check for accuracy,
effectiveness of examples, etc.

Feel free to mail me directly with comments or post them here.


I scanned through your article and it seemed very well written. I have a
little bit of feedback on a few sections that you may be interested in:

The section on volitile and stale data, I though the example and text was
good for beginners, but didn't touch on what was (is!) the biggest issue
there for me - that is the problem of "it runs great in debug mode, but when
I turn on optimizations my code doesn't work any more." issue. The way the
various optimizers can and do isolate variables inside loops and other very
subtle things has caught me by surprise on more than one occasion. Your
suggestion of wrapping things in a lock in order to avoid the 'volitile'
issue is excellent - especially as it'll work in VB.NET, which lacks the
volitile keyword.

The code samples in the "Stopping" section, I don't agree with. First the
Nitpicks:
You are using variables "stopping" and "stopped", and properties "Stopping"
and "Stopped". This naming convention shoud, I believe, be frowned upon.
Relying on case to differentiate members and properties is just asking for
trouble. It also violates the naming convention MS spells out in the MSDN
documentation for .NET.

I typically write this code as:

Private _stop As New Threading.Manua lResetEvent(Fal se)
Private _runningThread As Threading.Threa d

Public Sub StartTheThread( )
_stop.Reset()
_runningThread = New Threading.Threa d(AddressOf MyThread)
_runningThread. Start()
End Sub

Public Sub StopTheThread()
_stop.Set()
_runningThread. Join()
End Sub

Private Sub MyThread()
While Not _stop.WaitOne(0 , False)
' Do Work Here
End While
End Sub

I prefer this over your sample for a few reasons
1 - It is my belief (I have not benchmarked it, although I should) that
testing an event for Set/Not-Set is much cheaper than acquiring and
releasing a monitor (potentially) several millions times per second.

2 - If my thread loop doesn't have to run "as fast as it can", I can easilyl
change the to "While Not _stop.WaitOne(1 000, False)" to make my loop run
once per second, while at the same time being responsive to shutdown events.
In your sample code, I would need to use a Sleep to slow down the loop,
which makes the thread unresponsive to shutting down.

3 - Your code is, in essece, creating a Manual Reset Event. Why create
something that's already there?
There were a few sections that I would have liked to see in there - mostly
these are questions that I've had for a while, and haven't ever been able to
get good ansers to..

1 - Something that I've looked for information on, and found absolutly
nothing, is the "Synchroniz ed" version of the various collection classes. I
have ended up having to roll my own collections in many cases, as I need to
access them from multiple threads (I am sooooo looking forward to
Generics!). With the lack of documentation on the synchronized collection
classes, I was never comfortable using them. What about them is thread safe?
I'm pretty sure Iteration is not (although it could be - the iterator could
grab a lock, and prevent other iterators from proceeding until it's
complete). Hashtables say (somewhere) that "one writer and multiple readers"
is thread safe, but I've never been quite sure of that. What about the other
collections?

2 - Some of the Win32 threading constructs that people have been using for
so long are not present in .NET. Specifically Semaphores and (I think) Named
Events. Any idea why?

3 - Some suggestions on how to start debugging threaded code. These could be
simple suggestions like "Give all your threads unique names, so that then
you're looking at the Threads window in the debugger, you can quickly tell
which thread is which", or complex suggestions like "Use SoS to determine
which thread is holding a lock".

4 - You don't have a section on Events (either Manual or AutoReset). Along
with Monitors, these are the most used threading constructs.

5 - ReaderWriterLoc ks are handy at times, but are probably beyond the scope
of your article.

6 - Another advanded topic that I've seen little on, but seems as if it
could be really usefull, is the ability of the Threadpool to have a Handle
bound to it, and provide callbacks when this handle changed. Can I bind
standard wait handles to the thread pool so that I can callbacks whenever a
manual or auto-reset even is changed? It seems as if there would probably be
some fascinating use cases for this...

--
Chris Mullins

Jul 21 '05 #2
Very nice article; had a quick look through it, its an easy way to explain
not-so-easy issues :)

Back in the VB days everybody wanted multi-threads (even did it with api
*highly unstable*) but now I don´t see people using it as much on .NET as it
would seem natural to.

I myself had a time and half on a multi-threading application on .NET where
I learned just how messy can it get without some sort of mutex.
Jul 21 '05 #3
A good addition might be a discussion of ManualResetEven t and AutoResetEvent
especially the differences between them and when they are appropriate ... I
get questions on that all the time.

Greg

"Jon Skeet [C# MVP]" <sk***@pobox.co m> wrote in message
news:MP******** *************** *@msnews.micros oft.com...
Please excuse the cross-post - I'm pretty sure I've had interest in the
article on all the groups this is posted to.

I've finally managed to finish my article on multi-threading - at least
for the moment. I'd be *very* grateful if people with any interest in
multi-threading would read it (even just bits of it - it's somewhat
long to go through the whole thing!) to check for accuracy,
effectiveness of examples, etc.

Feel free to mail me directly with comments or post them here.

The article is at:
http://www.pobox.com/~skeet/csharp/multithreading.html

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

Jul 21 '05 #4
Greg Young <gr********@pla netbeach.com> wrote:
A good addition might be a discussion of ManualResetEven t and AutoResetEvent
especially the differences between them and when they are appropriate ... I
get questions on that all the time.


Right. That's two requests for them: they're definitely going in. This
is a good opportunity to get myself more thoroughly familiar with them,
too :)

--
Jon Skeet - <sk***@pobox.co m>
http://www.pobox.com/~skeet
If replying to the group, please do not mail me too
Jul 21 '05 #5
<ca*****@hotmai l.com> wrote:
Very nice article; had a quick look through it, its an easy way to explain
not-so-easy issues :)
Cool, thanks :) As with most of the articles, it was born out of
laziness: I don't want to spend ages typing the same kinds of answer
out again and again!
Back in the VB days everybody wanted multi-threads (even did it with api
*highly unstable*) but now I don´t see people using it as much on .NET as it
would seem natural to.
Interesting. I certainly cringe when Application.DoE vents is
recommended for something which naturally lends itself to multiple
threads.
I myself had a time and half on a multi-threading application on .NET where
I learned just how messy can it get without some sort of mutex.


I would laugh, but the memory of similar situations is too painful ;)

--
Jon Skeet - <sk***@pobox.co m>
http://www.pobox.com/~skeet
If replying to the group, please do not mail me too
Jul 21 '05 #6
Chris Mullins <cm******@yahoo .com> wrote:
"Jon Skeet [C# MVP]" wrote:

I've finally managed to finish my article on multi-threading - at least
for the moment. I'd be *very* grateful if people with any interest in
multi-threading would read it (even just bits of it - it's somewhat
long to go through the whole thing!) to check for accuracy,
effectiveness of examples, etc.

Feel free to mail me directly with comments or post them here.
I scanned through your article and it seemed very well written. I have a
little bit of feedback on a few sections that you may be interested in:

The section on volitile and stale data, I though the example and text was
good for beginners, but didn't touch on what was (is!) the biggest issue
there for me - that is the problem of "it runs great in debug mode, but when
I turn on optimizations my code doesn't work any more." issue. The way the
various optimizers can and do isolate variables inside loops and other very
subtle things has caught me by surprise on more than one occasion. Your
suggestion of wrapping things in a lock in order to avoid the 'volitile'
issue is excellent - especially as it'll work in VB.NET, which lacks the
volitile keyword.


I can't work out whether I'm surprised that VB.NET lacks volatile or
not - I think I *may* have tried to find an equivalent and failed, but
I'm not sure.

It's a good point though - I think I've specified somewhere that "it
works for me" isn't a good enough reason to believe the code is valid,
but I'll emphasise it much more. Good catch.
The code samples in the "Stopping" section, I don't agree with. First the
Nitpicks:
You are using variables "stopping" and "stopped", and properties "Stopping"
and "Stopped". This naming convention shoud, I believe, be frowned upon.
Relying on case to differentiate members and properties is just asking for
trouble. It also violates the naming convention MS spells out in the MSDN
documentation for .NET.
It doesn't - the naming convention MS uses specifically doesn't mention
private members. It's not a problem for VB users because anyone outside
the class doesn't see the variables at all.

I've used the convention for years in both Java and C# and *never* had
a problem with it as far as I can remember. I find code written with my
convention significantly easier to use than code which uses underscores
all over the place - they just look horribly ugly to me, and disturb my
train of thought when I'm reading.

I'm afraid I'll stick with my convention as I do for all my code
samples.
I typically write this code as:

Private _stop As New Threading.Manua lResetEvent(Fal se)
Private _runningThread As Threading.Threa d

Public Sub StartTheThread( )
_stop.Reset()
_runningThread = New Threading.Threa d(AddressOf MyThread)
_runningThread. Start()
End Sub

Public Sub StopTheThread()
_stop.Set()
_runningThread. Join()
End Sub

Private Sub MyThread()
While Not _stop.WaitOne(0 , False)
' Do Work Here
End While
End Sub

I prefer this over your sample for a few reasons
1 - It is my belief (I have not benchmarked it, although I should) that
testing an event for Set/Not-Set is much cheaper than acquiring and
releasing a monitor (potentially) several millions times per second.
That's a heck of an assumption, in my view. Rather than making any
assumptions, I decided to test it. The main code in both my tests was
the same:

using System;
using System.Threadin g;

public class LockTest
{
static void Main()
{
Worker worker = new Worker();
new Thread(new ThreadStart(wor ker.Run)).Start ();
Thread.Sleep(10 000);
worker.Stop();
}
}

The worker object for my version is as on the website (except with
stopLock declared as object, not bool - oops! Fixed the website now)
but with a long counter variable which is just incremented in the loop
in the same way as with the code below, which is a slightly simplified
version of what you posted (just for the purposes of this test):

public class Worker
{
long counter=0;

ManualResetEven t stop = new ManualResetEven t(false);

public void Stop()
{
stop.Set();
}

public void Run()
{
DateTime start = DateTime.Now;
while (!stop.WaitOne( 0, false))
{
counter++;
}
DateTime end = DateTime.Now;
Console.WriteLi ne
("Count per second: {0}", counter/(end-start).TotalSec onds);
}
}

Results (3 tests each):

Using a lock:
Count per second: 28038249.614792
Count per second: 28113891.755868 5
Count per second: 27467033.439749 6

Using a manual reset event:
Count per second: 1087057.6
Count per second: 1086289.8278560 2
Count per second: 1082087.3

So on average, using a lock we're able to count about 25 times as fast.

Just another example of threading not being a good thing to guess about
:)

I'd be very interested to see whether you get the same kind of results
- it may *very* well depend to a very large extent on the CPU(s) of the
test machines. Mine is a P4/3.06GHz laptop; no hyperthreading or
anything like that. I'd be particularly interested to know the numbers
on a dual processor machine...
2 - If my thread loop doesn't have to run "as fast as it can", I can easilyl
change the to "While Not _stop.WaitOne(1 000, False)" to make my loop run
once per second, while at the same time being responsive to shutdown events.
In your sample code, I would need to use a Sleep to slow down the loop,
which makes the thread unresponsive to shutting down.
Well, I'd probably use Monitor.Wait in that case, myself. I'm happier
with Monitor than reset events, but either would work fine here. I
wouldn't usually limit it artificially like that though - normally if
there's a reason to slow something down, that's because it hasn't got
work the whole time - and there I'd use a work queuing system. If I
want a thread to essentially be at a lower priority, I'll just lower
the priority. (Ah - another thing I haven't covered :)
3 - Your code is, in essece, creating a Manual Reset Event. Why create
something that's already there?
It's not, really. There's much more to events than just testing and
setting, as you've already shown with WaitOne - there are also calls to
wait for potentially many events at a time, etc. I believe testing a
boolean (even in a lock) is significantly simpler and easier to
understand than ManualResetEven ts, which is why I stick with them in
general.
There were a few sections that I would have liked to see in there - mostly
these are questions that I've had for a while, and haven't ever been able to
get good ansers to..
I'll present quick answers here (to a couple of them), and see if there
are other comments in this thread (no pun intended). I'll then see
which bits are appropriate for inclusion in the article itself.
1 - Something that I've looked for information on, and found absolutly
nothing, is the "Synchroniz ed" version of the various collection classes. I
have ended up having to roll my own collections in many cases, as I need to
access them from multiple threads (I am sooooo looking forward to
Generics!). With the lack of documentation on the synchronized collection
classes, I was never comfortable using them. What about them is thread safe?
I'm pretty sure Iteration is not (although it could be - the iterator could
grab a lock, and prevent other iterators from proceeding until it's
complete). Hashtables say (somewhere) that "one writer and multiple readers"
is thread safe, but I've never been quite sure of that. What about the other
collections?
I believe the idea of synchronized collections is that each individual
operation automatically takes out a lock, but that in order to
synchronize a whole series of operations, you need to lock on the
SyncRoot of the collection.

I've seen the same statement about multiple readers and a single writer
for hashtable, but I haven't tried to verify it with stress testing or
anything like that.
2 - Some of the Win32 threading constructs that people have been using for
so long are not present in .NET. Specifically Semaphores and (I think) Named
Events. Any idea why?
I really don't know. Semaphores are handy constructs, and fairly easily
built out of monitors (so long as you're careful :) I may present a
sample semaphore class for those who are interested. I wouldn't be at
all surprised if they made it into .NET v2 anyway though.
3 - Some suggestions on how to start debugging threaded code. These could be
simple suggestions like "Give all your threads unique names, so that then
you're looking at the Threads window in the debugger, you can quickly tell
which thread is which", or complex suggestions like "Use SoS to determine
which thread is holding a lock".
Right, that's a good idea.
4 - You don't have a section on Events (either Manual or AutoReset). Along
with Monitors, these are the most used threading constructs.
Funnily enough, I've virtually never used them - except to build a
fuller Monitor implementation for the Compact Framework :)

I suspect it's my Java background showing through to some extent, but I
more naturally think in terms of monitors, and they tend to do
everything I need them to. I think they're generally simpler, which is
another reason I use them :) (I do use Events when I want to wait for
multiple conditions etc.)
5 - ReaderWriterLoc ks are handy at times, but are probably beyond the scope
of your article.
Not sure - I think that's a very good idea. I haven't had to use them
myself, but almost certainly will at some time. I'll take a bit of a
breather and then probably add a section about them.
6 - Another advanded topic that I've seen little on, but seems as if it
could be really usefull, is the ability of the Threadpool to have a Handle
bound to it, and provide callbacks when this handle changed. Can I bind
standard wait handles to the thread pool so that I can callbacks whenever a
manual or auto-reset even is changed? It seems as if there would probably be
some fascinating use cases for this...


Mmm... I really don't know *anything* about that topic. Sounds like
something it would be worth investigating.. .

--
Jon Skeet - <sk***@pobox.co m>
http://www.pobox.com/~skeet
If replying to the group, please do not mail me too
Jul 21 '05 #7

"Jon Skeet [C# MVP]" wrote:
Chris Mullins <cm******@yahoo .com> wrote:
Your
suggestion of wrapping things in a lock in order to avoid the 'volitile'
issue is excellent - especially as it'll work in VB.NET, which lacks the
volitile keyword.
I can't work out whether I'm surprised that VB.NET lacks volatile or
not - I think I *may* have tried to find an equivalent and failed, but
I'm not sure.


I've looked several times for it, and each time been quite shocked not
to find it. I always feel if I dig "just a bit deeper" I'll find it. Ah
well.
One more thing that occasionally forces me to write code in C#...
You are using variables "stopping" and "stopped", and properties "Stopping" and "Stopped". This naming convention shoud, I believe, be frowned upon.
[...]
I've used the convention for years in both Java and C# and *never* had
a problem with it as far as I can remember. I'm afraid I'll stick with my convention as I do for all my code
samples.
'Fair Nuff. I still think it's evil though.
I prefer this over your sample for a few reasons
1 - It is my belief (I have not benchmarked it, although I should) that
testing an event for Set/Not-Set is much cheaper than acquiring and
releasing a monitor (potentially) several millions times per second.


That's a heck of an assumption, in my view. Rather than making any
assumptions, I decided to test it.


[...]
Results (3 tests each):

Using a lock:
Count per second: 28038249.614792
Count per second: 28113891.755868 5
Count per second: 27467033.439749 6

Using a manual reset event:
Count per second: 1087057.6
Count per second: 1086289.8278560 2
Count per second: 1082087.3

So on average, using a lock we're able to count about 25 times as fast.


Wow. I should know better by now than to make assumptions on these
things. That's what Compuware's profiler is for.
1 - Something that I've looked for information on, and found absolutly
nothing, is the "Synchroniz ed" version of the various collection classes. I have ended up having to roll my own collections in many cases, as I need to access them from multiple threads (I am sooooo looking forward to
Generics!). With the lack of documentation on the synchronized collection classes, I was never comfortable using them. What about them is thread safe? I'm pretty sure Iteration is not (although it could be - the iterator could grab a lock, and prevent other iterators from proceeding until it's
complete). Hashtables say (somewhere) that "one writer and multiple readers" is thread safe, but I've never been quite sure of that. What about the other collections?


I believe the idea of synchronized collections is that each individual
operation automatically takes out a lock, but that in order to
synchronize a whole series of operations, you need to lock on the
SyncRoot of the collection.


I'm pretty sure this is what they do too, but I've never seen this actually
documented anywhere. Their complete non-existance on the CF has meant
that I needed to write my own thread-safe collections anyway, so I've
never looked into them in great detail. (But for a threading article on the
standard CLR, I think they're a good topic)
2 - Some of the Win32 threading constructs that people have been using for so long are not present in .NET. Specifically Semaphores and (I think) Named Events. Any idea why?


I really don't know. Semaphores are handy constructs, and fairly easily
built out of monitors (so long as you're careful :) I may present a
sample semaphore class for those who are interested. I wouldn't be at
all surprised if they made it into .NET v2 anyway though.


The one thing that Semaphores have, that I don't think you can duplicate
with Monitors, is that they're cross-process. They're really handy for "Is
my application already running?" checks, as well as a wide variety of
other computer-wide resource management tricks.
4 - You don't have a section on Events (either Manual or AutoReset). Along with Monitors, these are the most used threading constructs.


Funnily enough, I've virtually never used them - except to build a
fuller Monitor implementation for the Compact Framework :)


That's funny - I used a combination of Win32 calls and Monitors to
implement a full ManualReseteven t on the compact framework.

For some silly reason there is no WaitHandle.Wait One(Timeout, false)
overload on the CF, which makes the class pretty useless for a wide
vareity of useses.. It's either wait forever, or don't wait at all. If
you want the source to this, drop me an email some time.

(That's the least I can do for you writing that UTF32String class a few
weeks back)

--
Chris Mullins
Jul 21 '05 #8
Chris Mullins <cm******@yahoo .com> wrote:
I can't work out whether I'm surprised that VB.NET lacks volatile or
not - I think I *may* have tried to find an equivalent and failed, but
I'm not sure.
I've looked several times for it, and each time been quite shocked not
to find it. I always feel if I dig "just a bit deeper" I'll find it. Ah
well.
One more thing that occasionally forces me to write code in C#...


Reflector decompiles a volatile variable as having ModReq(IsVolati le)
after it, which I believe is what's in IL. It doesn't look like you can
apply that within VB though.

<big snip>
I believe the idea of synchronized collections is that each individual
operation automatically takes out a lock, but that in order to
synchronize a whole series of operations, you need to lock on the
SyncRoot of the collection.


I'm pretty sure this is what they do too, but I've never seen this actually
documented anywhere. Their complete non-existance on the CF has meant
that I needed to write my own thread-safe collections anyway, so I've
never looked into them in great detail. (But for a threading article on the
standard CLR, I think they're a good topic)


Right. I might see what else I can dig up about them - without the
source code being available, it's hard to say. I can always look at the
Rotor implementation, I suppose.
I really don't know. Semaphores are handy constructs, and fairly easily
built out of monitors (so long as you're careful :) I may present a
sample semaphore class for those who are interested. I wouldn't be at
all surprised if they made it into .NET v2 anyway though.


The one thing that Semaphores have, that I don't think you can duplicate
with Monitors, is that they're cross-process. They're really handy for "Is
my application already running?" checks, as well as a wide variety of
other computer-wide resource management tricks.


Ah - I've been thinking in terms of the computer science idea of a
counting semaphore, rather than the Win32 specific concept.

For cross-process "am I running" checks, however, a Mutex works pretty
well. See
http://www.pobox.com/~skeet/csharp/f...ation.instance

I dare say there are other uses which Mutex wouldn't cut it for though.
Funnily enough, I've virtually never used them - except to build a
fuller Monitor implementation for the Compact Framework :)


That's funny - I used a combination of Win32 calls and Monitors to
implement a full ManualReseteven t on the compact framework.

For some silly reason there is no WaitHandle.Wait One(Timeout, false)
overload on the CF, which makes the class pretty useless for a wide
vareity of useses.. It's either wait forever, or don't wait at all. If
you want the source to this, drop me an email some time.


Have you thought about contributing it to OpenNETCF? That's what I did
with what is now called MonitorEx. I had the same problem as you did
though - I can't implement Wait with a timeout. I suspect if either of
us could implement one of them, we could use it to implement the other
:)

(I had a few ideas about how to do it using timers, but the ideas
became pretty horrible.)
(That's the least I can do for you writing that UTF32String class a few
weeks back)


Ah, that was for you, was it? I couldn't remember. Did you ever use it,
or were you able to make do with a couple of bits of it? It was fun
writing it either way :) (I dread to think what that says about me...)

--
Jon Skeet - <sk***@pobox.co m>
http://www.pobox.com/~skeet
If replying to the group, please do not mail me too
Jul 21 '05 #9
Brian Gideon <Br*********@di scussions.micro soft.com> wrote:
It's been a while since I've monitored usenet, but with this slick
web-based interface at the MSDN site I might be a frequent visitor.
I think I'll always favour a "proper" newsreader app myself, but each
to their own :)
Anyway, multithreaded applications have always interested me so your
post naturally stuck out like a sore thumb. You have a very nice
article and coming from you I think we can all count on quality
information. Nice job!


Thanks - but until it's been vetted by a few people who know more than
I do, I wouldn't assume absolutely everything's right. I've tried to be
as accurate as I can, but as I state at the start of the article, I'm
far from being an expert on it. Trouble is, I don't want to bother the
real experts too much by asking them to look at it :)

--
Jon Skeet - <sk***@pobox.co m>
http://www.pobox.com/~skeet
If replying to the group, please do not mail me too
Jul 21 '05 #10

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

Similar topics

7
1833
by: Max | last post by:
One of the most common situations I keep finding myself in when creating or working on an MS Access db is figuring out how to relate a table that actually has a place in more than 1 tiered one-to-many related tables. Let me explain: The easiest example is a phone number in a multi-level organized company... Lets say you have a main Regional Office. Under that Regional Office, you have about 5 or 6 Area Offices that are all considered...
0
1699
by: TSD 2006 | last post by:
********************************************************* TSD 2006 - CALL FOR PARTICIPATION ********************************************************* Ninth International Conference on TEXT, SPEECH and DIALOGUE (TSD 2006) Brno, Czech Republic, 11-15 September 2006 http://www.tsdconference.org/ The conference is organized by the Faculty of Informatics, Masaryk University, Brno, and the Faculty of Applied Sciences, University of
6
1701
by: pythonblogs | last post by:
Hello! It seems like Python blogs are gaining popularity. It seems to me that they play a crucial role in promoting Python as a language. Do you agree with that? Just a few days ago I've finished setting up a dedicated Python blogging environment at: http://www.pythonblogs.com Do you think it will be useful for Python community?
0
8590
marktang
by: marktang | last post by:
ONU (Optical Network Unit) is one of the key components for providing high-speed Internet services. Its primary function is to act as an endpoint device located at the user's premises. However, people are often confused as to whether an ONU can Work As a Router. In this blog post, we’ll explore What is ONU, What Is Router, ONU & Router’s main usage, and What is the difference between ONU and Router. Let’s take a closer look ! Part I. Meaning of...
0
8524
by: Hystou | last post by:
Most computers default to English, but sometimes we require a different language, especially when relocating. Forgot to request a specific language before your computer shipped? No problem! You can effortlessly switch the default language on Windows 10 without reinstalling. I'll walk you through it. First, let's disable language synchronization. With a Microsoft account, language settings sync across devices. To prevent any complications,...
0
8947
jinu1996
by: jinu1996 | last post by:
In today's digital age, having a compelling online presence is paramount for businesses aiming to thrive in a competitive landscape. At the heart of this digital strategy lies an intricately woven tapestry of website design and digital marketing. It's not merely about having a website; it's about crafting an immersive digital experience that captivates audiences and drives business growth. The Art of Business Website Design Your website is...
1
8779
by: Hystou | last post by:
Overview: Windows 11 and 10 have less user interface control over operating system update behaviour than previous versions of Windows. In Windows 11 and 10, there is no way to turn off the Windows Update option using the Control Panel or Settings app; it automatically checks for updates and installs any it finds, whether you like it or not. For most users, this new feature is actually very convenient. If you want to control the update process,...
1
6450
isladogs
by: isladogs | last post by:
The next Access Europe User Group meeting will be on Wednesday 1 May 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 a new presenter, Adolph Dupré who will be discussing some powerful techniques for using class modules. He will explain when you may want to use classes instead of User Defined Types (UDT). For example, to manage the data in unbound forms. Adolph will...
0
5806
by: conductexam | last post by:
I have .net C# application in which I am extracting data from word file and save it in database particularly. To store word all data as it is I am converting the whole word file firstly in HTML and then checking html paragraph one by one. At the time of converting from word file to html my equations which are in the word document file was convert into image. Globals.ThisAddIn.Application.ActiveDocument.Select();...
0
4541
by: adsilva | last post by:
A Windows Forms form does not have the event Unload, like VB6. What one acts like?
1
2960
by: 6302768590 | last post by:
Hai team i want code for transfer the data from one system to another through IP address by using C# our system has to for every 5mins then we have to update the data what the data is updated we have to send another system
3
1947
bsmnconsultancy
by: bsmnconsultancy | last post by:
In today's digital era, a well-designed website is crucial for businesses looking to succeed. Whether you're a small business owner or a large corporation in Toronto, having a strong online presence can significantly impact your brand's success. BSMN Consultancy, a leader in Website Development in Toronto offers valuable insights into creating effective websites that not only look great but also perform exceptionally well. In this comprehensive...

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.