I gave you the Answers to your previous Questions with a lot of instructions. I don't see a trace of that design, which is a must, as I can see now.
The number of file structure items can be way too big, so loading them all at once can easily deplete you memory. I recommended a schema of "virtual" tree behavior based on the expanding/collapsing events; where is this code?
Virus scan is not a directory scan, it takes significant time. So, first question is: where do you create you virus-scanning thread? If you did not do it, or if this is the same as your UI thread — just forget your project!
By the way, the simple rule of thumb about
Application.DoEvent
: never ever use it! I do not fully understand why so many developer think it can help and make this mistake over and over! Not using this API is one of the most popular topics here at CodeProject Questions; many experts already recommended not using it. It works in the UI thread, but you need at least two parallel thread of execution.
Here is how your design should look: you need to create an extra thread for virus scan. It should work all the time and sleep until you give it a task to scan. The thread should work in infinite loop, repeating full scan cycle on request. When the user click "Scan!" it should feed the data on the top-level scan directory (plus options) and wake up the thread, and the thread should start scanning. You UI should stay responsive all the time. For the scan results, you need a view. It can be just a list view (better than the tree), the virtual nature of it I explained in my previous Answers:
Is there a quicker way to list folders and subfolders?[
^] and
Need Some Expert Help With Treeview Scan Please[
^].
I recommend using thread wrapper as shown in my sample code here:
How to pass ref parameter to the thread[
^]. This provides a safe way of delivering of any parameters the the thread. Similar idea can work for scheduling a thread pool thread or
System.ComponentModel.BackgroundWorker
(see below). Another way of feeding working data to a thread is a blocking queue. Please see full sample code in my Tip/Trick Article
Simple Blocking Queue for Thread Communication and Inter-thread Invocation[
^].
The alternative solution is to create a thread each time you have a request to scan. As you have only one thread at a time (not counting your UI thread) and because the thread cycle takes way more time then its creation, it does not really matter. You can create a regular thread via
System.Threading.Thread
constructor, use a thread from a thread pool or use
System.ComponentModel.BackgroundWorker
.
As a virus is found, the thread should notify UI using
System.Windows.Forms.Control.BeginInvoke
. You cannot handle UI controls from non-UI thread using direct calls or accessing any properties (reading/writing properties is essentially a call as well). The call to
BeginInvoke
will package all the data needed for the call in a queue. This call is non-blocking, so the it returns to the caller immediately after the data goes to the queue, not waiting for the actual call of the delegate. The queue is read by UI in its main cycle (of
Application.Run
) and actual calls are done in UI thread. (In principle, understanding of this mechanism can give you and idea of why
DoEvent
is bad.)
This is only a short overview. I can see you're not even close so far. The work is relatively big even if your virus-specific code is ready. By the way, you should also thoroughly isolate you UI from semantic part of functionality. I'm afraid I'm not really sure that you can do it yourself before you learn an order of magnitude more compared to what you can do now.
—SA