Click here to Skip to main content
15,867,568 members
Please Sign up or sign in to vote.
0.00/5 (No votes)
See more:
Hi guys,

Okay, so I'm not sure if this is possible/advisable so looking for guidance with this one please.
Basically I am developing a process that reads through an excel spreadsheet (not in excel).
For each row the process looks into a secondary data store to pull out information based on two columns in the excel sheet. Most of the time only one result will be found each time, however occasionally the following will occur:

a) 0 results are found
b) more than 1 result is found

I want to be able to display a form to the user so they can alter the text it searched on, or they can choose to skip the record.

This is processing large files with in-excess of 2000 rows and is also using a fairly slow API for querying the second data store (it is third party so have to access it this way).

I would ideally like to run the processing on a different thread to the main UI which is a MVVM WPF application so that I can update a log showing progress for each row that is handled.

Now, I'm okay with a background worker, but I'm not sure how I can have UI input on the odd records using a background worker? Is this possible?
Is there a better way I could utilize threading to do this and still maintain a responsive UI and have prompts as/when required?

Thanks in advance.
Posted
Comments
Sergey Alexandrovich Kryukov 8-Aug-13 12:33pm    
Yes, this is quite possible, but will require very thorough design if you want to involve some decision-making during the process. So, what's your problem? Do you know the Dispatcher?
—SA
Pheonyx 8-Aug-13 15:47pm    
The only way i've done threading in the past is with the Background worker, I loosely understand what the Dispatcher is but i've never written code to use it before.
Sergey Alexandrovich Kryukov 8-Aug-13 16:10pm    
This is not always the best. You can always use the thread created from it's constructor (good for prolonged use or reuse), and thread pool. I often recommend first option with thread wrapper (very, very beneficial). And Dispatcher is needed to invoke UI methods to UI thread. Need help with that?
—SA
Pheonyx 8-Aug-13 16:15pm    
Any help you could provide with that would be greatly appreciated yes.
I thank you in advance for you help.
Sergey Alexandrovich Kryukov 8-Aug-13 16:29pm    
Just did, please see.
—SA

1 solution

Please see my comments to the question.

One approach alternative to the BackgroundWorker is using preliminary created thread, created through the constructor, which you can keep sleeping (wasting no CPU time for that, of course) and activate when the task is fed to it. This is a really good and stable variant of design, because you allocate all related resources only in the very beginning of runtime. Such throttling is done by the class System.Threading.ManualResetEvent:
http://msdn.microsoft.com/en-us/library/system.threading.manualresetevent.aspx[^].

You just reset or signal the event thread handle, and the thread calling its method WaitOne is put to the wait state of the event handle is non-signaled. The thread will be awaken when it is signaled or by some other conditions (abort or timeout).

One more specialized form of such behavior with zero-waste CPU can be achieved with the blocking queue. Please see my article on the topic:
Simple Blocking Queue for Thread Communication and Inter-thread Invocation.

As you can see, one kind of items you can feed to the queue could be delegate instances. This way, you can immediately feed tasks to the thread, and the thread will be waiting for the task, wasting no CPU time in the wait state. (And this is possible because threading is done based on interrupts.)

By the way, this is how invocation of the delegate instances to some UI thread is working with Dispatcher, which brings us to other problem: how to work with UI from some non-UI thread?

You cannot call anything related to UI from non-UI thread. Instead, you need to use the method Invoke or BeginInvoke of System.Windows.Threading.Dispatcher (for both Forms or WPF) or System.Windows.Forms.Control (Forms only).

You will find detailed explanation of how it works and code samples in my past answers:
Control.Invoke() vs. Control.BeginInvoke()[^],
Problem with Treeview Scanner And MD5[^].

Now, I promised to suggest thread wrapper and motivate it. Please read my past answers:
Thread wrapper,
Thread wrapper with lock: multithreading use,
Thread wrapper with event.

See also more references on threading:
How to get a keydown event to operate on a different thread in vb.net[^],
Control events not firing after enable disable + multithreading[^].

—SA
 
Share this answer
 
v2
Comments
Pheonyx 9-Aug-13 7:12am    
Thank you for this, it has proved exceptionally useful to understand using a thread wrapper class. Now I have that working, I need to look at pausing a running thread and allowing user interaction. Think that is a task for next week.

Thank you again :-)
Sergey Alexandrovich Kryukov 9-Aug-13 10:24am    
This is such a pleasure to help someone who can understand it and actually make things working.
Good luck, call again.
—SA

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)



CodeProject, 20 Bay Street, 11th Floor Toronto, Ontario, Canada M5J 2N8 +1 (416) 849-8900