It's the first time that I work on multithreading application (in general, not only with C#), and for this reason I know only simple notions about it. I've realized basically implementation with System.Threading namespace.
I've a dictionary which link objects A with its ID (Dictionary<int,A>). Every A has to do an operation (the same operation for every A), and I would like that this operations work in a list of separate thread, one for each A.
I know that System.Threading is bad way to realize multithreading, but I know a little bit only this namespace at this moment. I made something as:
public class ThreadManager
{
private Dictionary<int, A> _aList;
public Dictionary<int, A> AList
{
get { return _aList; }
set { _aList = value; }
}
private Dictionary<int, Thread> _threadList;
public Dictionary<int, Thread> ThreadList
{
get { return _threadList; }
set { _threadList = value; }
}
public ThreadManager(Dictionary<int, A> list)
{
AList = list;
ThreadList = new Dictionary<int, Thread>();
foreach (A a in AList)
{
int id = a.Id;
ThreadList.Add(id, new Thread(new ParameterizedThreadStart(Operation)));
}
}
public void Operation(object data)
{
try
{
/*** do something***/
}
catch (Exception e)
{
/*** throw exception ***/
}
}
}
When I run specific thread in out point of my application code with:
ThreadManager.ThreadList[i].Start(data)
it seems work fine to do needed operation. However, I think that this solution is really ugly and not very functional.
Furthermore, there is another big problem. When exception in throw, as expected, it isn't catch out of thread. Can I catch thread exception in another point of my code, which work on different thread (for example the main thread)?
Edit:
In order to be clear, I would like that no threads blocking main thread. I need to be able to operate on the main thread while operations work.
My suggestion it to use a combination of async/await,
Task.RunandParallel.ForEach:asyncandawaitkeywords allows you to write asynchronous code that doesn't block the UI thread, in the same way that you would write normal synchronous code. The UI remains responsive while the asynchronous operation is in-flight.Task.Runoffloads the processing of theactiondelegate to aThreadPoolthread. TheThreadPoolis a pool of reusable threads that is managed by the .NET infrastructure. In case it is necessary, you can fine-tune it with theThreadPool.SetMinThreadsmethod.Parallel.ForEachinvokes thebodydelegate in parallel on multipleThreadPoolthreads, enforcing aMaxDegreeOfParallelismpolicy. In case you want unlimited parallelism, configure it withMaxDegreeOfParallelism = -1.In case of an exception the
Parallel.ForEachwill stop invoking thebodydelegate, and will complete when all the currently running invocations have completed. The errors of all erroneous invocations will be bundled in anAggregateException. This exception will be propagated first by theTask.Runand then by theawaitoperator, and you will be able to handle it on the UI thread with thetry/catchblock inside theClickevent handler. You could also let it unhandled (omit thecatchblock), in which case it will be handled be the generalApplication.ThreadExceptionevent handler. If you omit this too, the user will be notified by the default error popup that the WinForms applications display by default, and gives the user the option to continue or exit the app.