When running this application, you won't get a deadlock. Instead you get an error stating that some data is corrupted within the DataTable
because the DataTable
itself has some internal checks for concurrency.
I suppose this application is a simpler version of your real app. There are a couple of steps you can take to improve your program:
- Avoid multithreading with shared data
Multithreading with shared data is hard. Can you simplify your program so that you don't need any shared data? Maybe you can run two operations in parallel, return a result and then merge those results. This would safe you from a lot of potential problems.
If that's not possible you can do the following:
- Add locks
You create a lock object like this:
private static object _lock = new object();
And now you surround calls to your datatable with:
lock (_lock)
{
dt.Rows.Add(i);
}
- Don't use Threads directly. Instead use the Task Parallel Library:
A Task
object is an intelligent wrapper around a Thread. Using Tasks is recommended.
Task t1 = Task.Run(() => P1(dt));
Task t2 = Task.Run(() => P2(dt));
Task.WaitAll(t1, t2);
UPDATE
Since the original question now changed from deadlock to freezes, there are a couple of other things you need to consider.
In a console application, you will always have to wait at some point until your two tasks finish. This waiting will freeze your UI. Off course you can use clever things like a Timer to check if the tasks are finished or something but a console application really isn't meant for a situation like this.
If however, your app is actually a WinForms or WPF app you should look at using asynchronous code with the new async/await keywords added in C# 5. They work perfectly with Tasks and they let you run code on another thread while the UI keeps responsive. When the Task finishes, the result is merged back on your UI thread and the user keeps a responsive app.
For more information on async/await, you can start here: Asynchronous Programming with Async and Await (C# and Visual Basic)