Question

Collections and Arrays

Asked by: orbitaltech

Anybody know how to copy a certian amount of items from a collection without having to loop the collection?

Basically something similar to Array.Copy(source,start, destination,count)

This Question has been solved and asker verified All Experts Exchange premium technology solutions are available to subscription members.

Subscribe now for full access to Experts Exchange and get

Instant Access to this Solution

  • Plus...
  • 30 Day FREE access, no risk, no obligation
  • Collaborate with the world's top tech experts
  • Unlimited access to our exclusive solution database
  • Never be left without tech help again

Subscribe Now

Asked On
2003-07-17 at 04:39:14ID20681244
Tags

array

Topic

C# Programming Language

Participating Experts
6
Points
500
Comments
30

Trusted by hundreds of thousands everyday for fast, accurate and reliable tech support.

  • "The time we save is the biggest benefit of Experts Exchange to Warner Bros. What could take multiple guys 2 hours or more each to find is accessed in around 15 minutes on Experts Exchange." Mike Kapnisakis, Warner Bros.
  • "Our team likes having a resource that is more secure than just using Google and most experts using this service really know their stuff. It's nice to look here first versus using Google." Dayna Sellner, Lockheed Martin
  • "Anytime that I've been stumped with a problem, 9 out of 10 times Experts Exchange has either the accepted solution or an open discussion of the potential solution to the problem." Kenny Red, eBay Inc.

See what Experts Exchange can do for you.

Got a question?

We've got the answer.

Experts Exchange has been collecting answers to technology questions since 1996…3 million and counting! If you have a question, chances are we already have your answer.

Screenshot of Experts Exchange Knowledgebase

Need individual assistance?

Our experts are ready to help.

If you can't find the exact answer you're looking for, ask our exclusive community of 50,000 experts. You’ll get a personalized answer from a trusted professional.

Screenshot of Experts Exchange Knowledgebase

Want to learn from the best?

Read articles from industry experts.

Thousands of free tech tips, tricks, how-to’s and tutorials are available in our peer reviewed articles section. See for yourself how smart our experts are, no login required.

Screenshot of an Article

Working on a long term project?

Store your work and research.

Save solutions to your questions, answers you’ve discovered through searching plus helpful articles in your personal knowledgebase for easy future access.

Screenshot of Experts Exchange Knowledgebase

Access the answers to your technology questions today.

Subscribe Now

30-day free trial. Register in 60 seconds.

What Makes Experts Exchange Unique?

Members of the expert community talk about why the experience at Experts Exchange is different than what you will find anywhere else.

Trusted by the world's most respected brands.

image of each brand's logo

Faithfully serving IT professionals since 1996.

Experts Exchange Logo

Try it out and discover for yourself.

Subscribe Now

30-day free trial. Register in 60 seconds.

Related Solutions

  1. collection object
    hi i just want to know what are the advantages of using a collection object aside from being able to use for-each loop and better organization/management of item. wouldn't it be faster if i just used a multidim array? thanks
  2. Array in a Collection Class
    Hello, I have a Collection of Classes How can I create an array in this Classes, and how can i get acess to the array-elements? Bye Ramoni

Free Tech Articles

  1. WARNING: 5 Reasons why you should NEVER fix a computer for free.
    It is in our nature to love the puzzle. We are obsessed. The lot of us. We love puzzles. We love the challenge. We thrive on finding the answer. We hate disarray. It bothers us deep in our soul. W...
  2. SCCM OSD Basic troubleshooting
    SCCM 2007 OSD is a fantastic way to deploy operating systems, however, like most things SCCM issues can sometimes be difficult to resolve due to the sheer volume of logs to sift through and the dispe...
  3. Migrate Small Business Server 2003 to Exchange 2010 and Windows 2008 R2
    This guide is intended to provide step by step instructions on how to migrate from Small Business Server 2003 to Windows 2008 R2 with Exchange 2010. For this migration to work you will need the fo...
  4. Create a Win7 Gadget
    This article shows you how to create a simple "Gadget" -- a sort of mini-application supported by Windows 7 and Vista. Gadgets can be dropped anywhere on the desktop to provide instant information, ...
  5. Outlook continually prompting for username and password
    There have been a lot of questions recently regarding Outlook prompting for a username and password whilst using Exchange 2007. There are a few reasons why this would happen and I will try to cover t...
  6. Backup Exchange 2010 Information Store using Windows Backup
    There seems to be quite a lot of confusion around the ability to backup Exchange 2010 using the built in Windows Backup feature. This stems from the omission of this feature prior to Exchange 2007 s...

Cloud Class Webinars

  1. Avoiding Bugs in Microsoft Access
    Alison Balter takes and in-depth look at avoiding bugs in Access. In this webinar you will learn about using the immediate window to debug your applications, invoking the debugger, using breakpoints to troubleshoot, stepping through code, setting the next statement to execute, ...
  2. Top 10 Best New Features in Visio 2010
    Scott Helmers gives live demonstrations of the top 10 new features in Visio 2010. This webinar will teach you how to create compelling diagrams by adding shapes to the page with a single click, linking the shapes in a diagram to data in Excel (or SQL Server, or SharePoint), ...
  3. IT Consultant Business Secrets Revealed
    Michael Munger, Experts Exchange tech pro and IT consultant, pulls back the curtain on his very successful businesses and answers question on every IT consultant and business owner should know about. He shares secrets on what he did to solve the 5 most common problems in IT, ...
  4. Disaster Recovery and Business Continuity
    Quest CTO, Mike Billon, gives an overview of the steps involved in building a dunamic disaster recovery plan. Through case studies and an examination of software/hardware tooles for monitoring and testing, you'll gain a better understandin of where you are, where you want ...
  5. Organize Your Visio Diagrams with Containers and Lists
    Scott Helmers uses cross functional flowcharts, wireframe diagrams, data graphic legends and seating charts to teach you: how to ustilize all three new structured diagram components in Visio 2010, the best practices for organizeing shapes in previous version of Visio, how to organize ...
  6. How to Us Objects, Properties, Events and Methods in Microsoft Access
    Alison Dalter gives an in-depbth look at objects, properties, events and methods in Microsoft Access. In this webinar you will learn about using the object browser, referring to objects, working with properties and methods, working with object variables, understanding the ...

Join the Community

Give a Little. Get a Lot.

Join the community of experts here and help other tech pros by answering question in your area of expertise. You can earn FREE access to all Experts Exchange's premium features and resources.

Join the Community

Answers

 

by: testnPosted on 2003-07-17 at 05:00:30ID: 8941685

Collection to Collection...
ArrayList desc = new ArrayList(source);


Collection to Array
collection.CopyTo(destination,start);

 

by: orbitaltechPosted on 2003-07-17 at 05:03:18ID: 8941699

yes but that copies ALL of the items in the collection.. I only want to copy a few of them.. A range of items in the collection so to speak

 

by: DespPosted on 2003-07-17 at 05:16:12ID: 8941797

hi,
you can use Addrange and getrange to do that ...
here is some code:

ArrayList a = new ArrayList();
ArrayList b = new ArrayList();

b.Add(31); //add elemnts to a
b.Add(32);
b.Add(33);
b.Add(34);
b.Add(35);
b.Add(36);
b.Add(37);

a.AddRange(b.GetRange (2,3)); //add 3 elements from b to a

for (int i = 0;i<a.Count;i++)   //a contain 33,34,35
      MessageBox.Show(a[i].ToString());

 

by: orbitaltechPosted on 2003-07-17 at 05:21:31ID: 8941839

what are you guys doing??? I said a COLLECTION not an ArrayList.

A COLLECTION does NOT support the GetRange method.

 

by: WiBPosted on 2003-07-17 at 05:41:52ID: 8941984

Because collection doesn't have something similar to Array.Copy(...),

you could use CopyTo to copy ALL elements of collection into an existing Array and after
copy a section of that Array to another Array using Array.Copy(source,start, destination,count).
 

 

by: DespPosted on 2003-07-17 at 05:42:18ID: 8941988

Sir,
can i ask what kind of of Collection are you using? there are many in C#

 

by: orbitaltechPosted on 2003-07-17 at 06:23:14ID: 8942341

does not matter the collection in this case.. What I am looking for is a way to copy a specificied number of objects from a collection. That's not easy and I know it's not available in .NET that is why I am here..

I don't care if it's done in managed or unmanaged code..

 

by: SaltePosted on 2003-07-17 at 06:57:28ID: 8942678

The reason why Array.Copy functions exist is that you don't have to loop the array in order to copy it, there are faster ways.

For a general collection the ONLY way to access each member is to enumerate them, i.e.. a foreach loop. Even the internal implementation would have to make some loop of some kind and apart from lists and other sequences it isn't obvious exactly how you would want to loop them.

Do you want to traverse a tree in prefix, infix or postfix order?

Do you want to traverse a graph in breadth first or depth first order?

And since any internal implementation would have to be implemented by a foreach loop anyway and there are so many options to choose on exaclty how you want to iterate them, it is just as well to skip it and rather export a foreach mechanism to the end user so that he can choose how he or she wants to iterate the elements by himself or herself.

So the short answer is: No, there is no way, you have to loop through the elements. This is usually trivial to do though once you know the context where you want to do it.

Alf

 

by: orbitaltechPosted on 2003-07-17 at 07:07:41ID: 8942768

Salte,

I agree for the most part, it is trivial do loop a collection but it is SLOW to loop it. I am looking for a way to get a range of items in a collection with speed. I am sure there is a way to do it using the Windows API, I just don't know the calls.

Any ideas?

 

by: SaltePosted on 2003-07-17 at 08:04:11ID: 8943300

What do you mean by "slow" here?

Let's say I implement a list class.

class ListNode {
internal ListNode next;
internal object data;
}

class List : IEnumerable {
internal ListNode first;
internal ListNode last;

...blah blah blah various functions...

    ListEnumerator GetEnumerator()
    {
        return new ListEnumerator(first);
    }
};

class ListEnumerator : IEnumerator {
   private ListNode cur;
   private ListNode list;

   internal ListEnumerator(ListNode f) { list = f; cur = null; }

   public virtual bool MoveNext()
   {
        if (cur == null)
           cur = list;
        else
           cur = cur.next;
       return cur != null;
   }

    public virtual object Current()
    { return cur.data; }

    public virtual void Reset()
    { cur = null; }
}

Now you might think it is "slow" to use the enumerator but it is actually just as fast or slow as it would be to loop through the ListNode objects by yourself:

ListNode p = first;
while (p != null) {
     ...access p.data....
     p = p.next;
}

but this is only barely faster and actually after the CLI code has been compiled by the JIT compiler it might actually result in exactly the same machine code.

So, no, it isn't necessarily any slower than doing it "directly" and note that there is no faster way to walk through a list - it is an inherent property of a list that you have to walk through the list node by node.

The same consideration is for other collections.

The only exception is arrays or similar array-like data st        ListNode c = cur;
        if (c != null) {
           cur = c.next;
           return c.data;
       }
      return null;
ructures such as stringbuilder's strings (which actually are char[]  - i.e. array of char). For these the hardware often offer special instructions which can run through the array faster than you can do it in a loop.

Hope this answers your question.

Alf

 

by: orbitaltechPosted on 2003-07-17 at 08:16:56ID: 8943423

Salte,

Well in my experience I can copy 5000 items from one array to another in less than 1 second but when I loop through 5000 items in a collection using the enumerator, it takes about 5-10 seconds depending...

I am looking to reduce the time to the less than a second deal

 

by: SaltePosted on 2003-07-17 at 09:14:02ID: 8944043

What kind of collection are we talking about here? Usually enumreators are made so that they can find the element as fast as possible but what is "fast as possible" depends very much upon the data structure. For example if you have a tree structure I would imagine a looping through a range of the data structure IS much slower than just traversing the tree and doing short-cuts by dropping subtrees you know are without interest.

If you are in a current node in a tree and want to find the "next" node in order this is a rather complicated run, especially if you don't have a parent pointer in the tree node but even with a parent node the "next" node is found by a fairly tricky algorithm.

1. If the current node has a right subtree then it has nodes that is larger than itself in a subtree and so you find the smallest such value. This is found going down the right subtree and then follow the chain of left subtrees until you find a node without left subtrees. This is the next node.

2. If the current node has no right subtree then it is the largest value in its own subtree (with itself as root) and you have to check the parent node.

3a. If the current node is in the right subtree of the parent then it is the largest node in the paren't subtree as well so you move up the tree until you find a parent where the current node is in the left subtree and not the right. If you hit the root node and all pointers are the right subtree then the node was the largest node in the tree and you are done.

3b. If you find a node where the current node is in the left subtree then that node is the next node since that is the next value.

Something like this in C# code.

Node next(Node C)
{
     if (C.right != null) {
           C = C.right;
           while (C.left != null)
               C = C.left;
           return C;
     }
     Node P = C.parent;
     while (P != null && P.right == C) {
          C = P;
          P = P.parent;
     }
     // either P == null and we're done, return null
     // or P != null and P.right != C so P.left must equal C and so P is the next node.
    return P;
}

As you can see this is quite complicated and you might call it slow but it is as fast as you can get for a binary tree. Your problem isn't that it is slow, your problem is that you have either chosen the wrong type of collection or that you are trying to use the collection in a way it wasn't meant to be used.

If you could explain in more detail what type of collection you are using and what you are trying to do with it and why you want it to be that type of collection, maybe we can help.

Hope this explains.

Alf

 

by: orbitaltechPosted on 2003-07-17 at 09:18:55ID: 8944088

ok then...

The collection is an EventLogEntryCollection

I have about 5 of them in an ArrayList object.

and I am using it to populate a dynamic listview and I need to get the items out of the Collections and into an EventLogEntry[] array

 

by: _TAD_Posted on 2003-07-17 at 09:37:57ID: 8944284



Okay... Every collection I looked through (lists, sorted lists, array lists, Queues, hashtables, etc) has a copyTo or ToArray Function.  By implementing ICollection you will have a CopyTo function, so even if you have your own home grown collection you still have that function.

hence.... this code works.  I have a collection (a queue, and I only want to copy 3 elements from it)


                  Queue q = new Queue();

                  for(int x = 0; x<10; x++)
                        q.Enqueue(x);

                  object[] o = new object[3];

                  Array.Copy(q.ToArray(),4,o,0,3);      



// display results

                  for(int y = 0; y<o.Length; y++)
                        Console.WriteLine(((int) o[y]).ToString());

 

by: orbitaltechPosted on 2003-07-17 at 10:05:07ID: 8944504

_TAD_

I am not seeing this in the same way...

If I inherit from ICollection or IList, I do not get a ToArray Function???

 

by: SaltePosted on 2003-07-17 at 10:39:49ID: 8944774

Let me see if I get this right.

You have an array list containing 5 EventLogEntryCollection objects?

If so I suspect the reason for it being slow is due to the EventLogEntryCollection object being slow. This object is probably implemented through some form of list or array or perhaps even worse by doing RPC call to get each element. However, I would assume that the CopyTo function would be fast.... try this...

int k = 0;

foreach (EventLogEntryCollection ec in ArrayListOfEventLogEntryCollections)
    k += ec.Count;
EventLogEntry [] arr = new EventLogEntry[k];
k = 0;
foreach(EventLogEntryCollection ec in ArrayListOfEventLogEntryCollections) {
    ec.CopyTo(arr, k);
    k += ec.Count;
}
Ok, we loop twice, as I said, if you keep the count you can avoid that first loop.

The second loop should go as fast as it can go.

This is using CopyTo which people already at the first posting adviced you to do ;)

If you want to copy a range then that range is either:

1. Based on index (see below) or

2. Based on contents.

If it is 2 then you HAVE TO loop through each individual element of the collections, there's no way around it and presumably the enumerator for that collection is as fast as it can when looping through the elements.

If it is 1, then I can help you. Let's say you want to copy C elements starting from index S instead of all of them as the above loops do. Also, assume you want to copy them into an array starting from index V. V must have room for the elements copied.

int k = 0;
foreach (EventLogEntryCollection ec in TheArrayList) {
     k += ec.Count;

I could have made a break out of the loop when k >= S + C but there's no point since there's only 5 elements in the array list.

int j = S + C;
if (k < S)
    return -1; // no events before S

if (k < j) {
   j = k;
   C = j - S;
}
// check that the destination array has room for C entries after V i.e. V + C <= arr.Length;
if (V + C > arr.Length) {
    // arr isn't big enough, throw some argument exception or something.
}

k = 0;
int copied = 0;

foreach (EventLogEntryCollection ec in TheArrayList) {
    int u = k + ec.Count;
    // if    S <= k < S + C  then we must copy some elements.
    // specifically if S <= k  <= u < S + C then we copy the whole collection to the array:
    // if S <= k < S + C < u then we only copy part of the collection.
    // we may also have the situation that k < S < u <= S + C if so we also copy part of the collection.
    if (u < S) { // haven't started copy yet.
         // do nothing
    } else if (k < S) { // k < S <= u
        if (u < S + C) {
               // k < S <= u < S + C we need to copy from S to u - 1.
               // since ec is based on k so all index values in ec is relative to k.
               int to_copy = u - S;
              CopyTo(ec, S - k, arr, V, to_copy);
              V += to_copy;
              C -= to_copy;
              copied += to_copy;
              S = u;
        } else {
              // k < S <= S + C <= u, Thus the whole copying is within this segment of ec.
             CopyTo(ec,S-k,arr,V,C);
             break;
        }
    } else if (u < S + C)  { // S <= k < u < S + C, copy the whole segment to array.
        ec.CopyTo(arr,V);
        V += u - k;
        C -= u - k;
        S = u;
    } else { // S <= k < S + C <= u, copy from k to S + C.
       ec.CopyTo(arr,V);
        break;
    }
    return copied + C;
}

The CopyTo function needs to be written:

int CopyTo(EventLogEntryCollection ec, int start, EventLogEntry [] dest, int start2, int count)
{
    EventLogEntry[] temp = new EventLogEntry[ec.Count];
    ec.CopyTo(temp,0);
    return Array.Copy(temp,start,dest,start2,count);
}

Unfortunately, there's no CopyTo that only copies a range.

If you need to filter the elements based on contents there really is no other way other than either 1. loop through each element in the collection or 2. Use CopyTo to copy the elements to an array and then continue from there.

Hope this is of help.

Alf

 

by: SaltePosted on 2003-07-17 at 10:43:42ID: 8944806

Err.. the I... whatever are interfaces.... you do not INHERIT them... they a class cannot inherit from an interface. Only interfaces can inherit from interfaces.

What you think is inheritance is C#'s way of saying that a given class promises to IMPLEMENT the interface. I.e. you can specify an interface that contain a ToArray function but then YOU must write that function. The interface doesn't have any code you can use.

Alf

 

by: _TAD_Posted on 2003-07-17 at 10:53:31ID: 8944882

To clarify, any class that implements ICollection needs a function called CopyTo()

when implementing the ICOllection you also have a "Count" property as well as a IsSyncrhronized and SyncRoot Properties.

take a gander at this snippet


// I'm using an event log entry object
EventLogEntry e;
                  
//create an array of Icomponent Objects
IComponent[] c = new IComponent[10];

//create an array of generic objects
object[] obj = new object[10];

//copy eventlog entry array to Icomponent array en mass
e.Container.Components.CopyTo(c,0);

// copy eventlog entry data objects to generic object array
e.Data.CopyTo(obj,0);


and if you don't want to create a specific array of type IComponent, just declare it as a generic object array and then cast it as an IComponent when you use it.

e.Container.Components.CopyTo(o,0);
Console.WriteLine(((IComponent)obj[0]).ToString());

 

by: _TAD_Posted on 2003-07-17 at 10:58:22ID: 8944924



How are you declaring your Collections?

If you use a generic abstract class for your base declaration you don't always get all of the details that you want.


For instance...

Stream s = new MemoryStream();

will not have the full set of properties and methods of

MemoryStream s = new MemoryStream();


So in your case, if you are declaring your object like:

CollectionBase e = new EventLogEntry();  you may only have a subset of the total properties and methods available to you.


 

by: orbitaltechPosted on 2003-07-19 at 10:03:37ID: 8958830

Sorry for the delay.. had to deal with work :(

 

by: orbitaltechPosted on 2003-07-19 at 10:08:54ID: 8958852

I do like the idea's but what I am seeing with both Salte's and _TAD_'s code is that you guys are doing what I am trying to avoid: Using the copyTo function of the collection which copies all of the elements to an array. This is the slow part that I am trying to get around by using some other method to copy a specific number of items from the collection.

Salte,
I am using method #1 (by index) to try and make this copy work so we are good.

 

by: _TAD_Posted on 2003-07-19 at 10:31:55ID: 8958969



Orbital,
   There in might lay your problem.  You must remember that Microsoft has optimized all of its code to be the most efficient.  The only way that may be faster is to use pointers and pointer arithmetic.  But then you aren't really copying the array, you are only referencing portions of another array.  If that base array changes, then the array your are using gets all hosed up as well.




Here is a thought... Although I haven't tried it yet, so the theory may be better than the application.


Suppose you have an array of 10,000 elements, and you want roughly 1,000 of those elements.

What about multi-threading the copy process?


have one thread only copy the first 100 element to array1, have a second thread copy elements 101 to 200 to array2, etc, etc.

Then at the end you simply merge the arrays.


I'll have to run a few trials and see if the straight CopyTo function (for 1,000 elements) is faster than a multi-threaded app each copying 100 elements.  

 

by: orbitaltechPosted on 2003-07-19 at 10:34:55ID: 8958982

_TAD_,

it might work but keep this in mind.. I am displaying the record not too soon after they are copied.. so if the multithreaded approach is not faster then it will do me no good.

NOW, using pointer types and pointer arithmetic sounds like a plan.. My biggest problem is that I am not as proficient in pointer usage as I would like to be.. So if anyone has any samples of how I might accomplish my task using the pointer types then by all means...

 

by: SaltePosted on 2003-07-21 at 00:09:17ID: 8965441

Ok, yes, we use the CopyTo which copies the whole array. There is no other version available.

The only OTHER alternative is to loop through the set using enumerator. Normally an enumerator is written to work as fast as possible. I agree though that the collection support in C# is far from perfect.

int CopyTo(EventLogEntryCollection ec, int start1, EventLogEntry [] dest, int start2, int count)
{
    int x = 0;
    int y = start2;
    foreach (EventLogEntry e in ec) {
       if (x >= start1) {
           dest[y++] = e;
           if (--count == 0)
                     break;
       }
       ++x;
    }
    return y - start2;
}

Perhaps add some more index checking, for example I don't test if start2 + count >= dest.Length etc.

Note that I only walk through the initial part of the collection, when I have copied count elements I break.

I must start from beginning though and simply just count x up to start1 before I can do any copying. There's no way around that unless you know the internal details of the collection in question. I don't know how an EventLogEntryCollection is implemented.

Also, even an internal CopyTo function must scan through the elements in a manner similar to the one I use here, there's no way around that. This is frequently an inherent limitation with the collection itself - such as a list.

Alf

 

by: orbitaltechPosted on 2003-07-21 at 06:04:33ID: 8967155

alas, this is just way to slow for me to handle... I guess I will just have to find another way.

I am still intrested int he pointer types version

 

by: SaltePosted on 2003-07-21 at 06:14:39ID: 8967238

If you need to find another way you might opt to not use an EventLogEntryCollection at all.

If you do opt to use it you have no other choice but to use the functions provided by that collection.

Is it possible that the EventLogEntryCollection is accessing RPC or some such for each object and that is the reason why it is slow? If so there simply isn't much you can do about that unless you want to dig down to the RPC level yourself.

Alf

 

by: orbitaltechPosted on 2003-07-21 at 08:28:39ID: 8968280

I might just look into that and see

 

by: FurtyPosted on 2003-08-09 at 23:32:34ID: 9116266

This may not be the answer to your problem, but I didn't notice it mentioned in any of the posts above..

In .Net using a foreach loop to iterate through a collection is quite costly to performance, as the maximum value must be re-calculated by the CLR on each pass.

as an example:

foreach(object o in base.List)
{
// do something
}

Each pass of this iteration has to check to see if the loop has reached the length of the base.List collection - while this is easy to code, it is costly to performance.

The better way to do this would be:

for(int i=0; i < base.List.Count; i++)
{
  object o = base.List[i];
// do something
}

For large collections the second method can show substantial performance gains.
Hope this helps!

20120131-EE-VQP-002

3 Ways to Join

30-Day Free Trial

The Experts

98% positive feedback on 31,087 answers since March 2000. angeliii is a Microsoft Most Valuable Professional for his work with MS SQL Server & Develoment.

He has also proven his knowledge of Visual Basic Programming, PHP Scripting and Oracle Databases.

The Experts

97% positive feedback on 10,752 answers since July 2000. lrmoore has more than 18 years experience in the networking industry.

The six-time Mircosoft MVPs specialties include firewalls, virtual private networking, and network management.

Testimonials

"...and excellent source for support... Kind of like having your very own IT dept." Electriciansnet

Testimonials

"I was apprehensive at signing up at first. However... it has already made my life as an IT administrator much easier." JaCrews

Testimonials

"WOW! You guys have great, active, and knowledgeable people on here." moore50

Business Clients

Business Clients

In the Press

"If you’ve got a question... Experts Exchange can supply an answer.”

In the Press

"...an invaluable aid for both IT professionals and those who require tech support."

In the Press

"where IT professionals provide quick answers on just about any topic"

Business Account Plans

Loading Advertisement...