I'm trying to refactoring my project and now I'm trying to research for best ways to increase the application's performance.
Question 1. SpinLock vs Interlocked
To creating a counter, which way has better performance.
Interlocked.increament(ref counter)
Or
SpinLock _spinlock = new SpinLock()
bool lockTaken = false;
try
{
_spinlock.Enter(ref lockTaken);
counter = counter + 1;
}
finally
{
if (lockTaken) _spinlock.Exit(false);
}
And if we need to increment another counter, like counter2
, should we declare another SpinLock
object? or its enough to use another boolean
object?
Question 2. Handling nested tasks or better replacement
In this current version of my application, I used tasks, adding each new task to an array and then used Task.WaitAll()
After a lot of research I just figured out that using Parallel.ForEach
has better performance, But how can I control the number of current threads? I know I can specify a MaxDegreeOfParallelism
in a ParallelOptions
parameter, but the problem is here, every time crawl(url)
method runs, It just create another limited number of threads, I mean if I set MaxDegree
to 10, every time crawl(url)
runs, another +10 will created, am I right?, so how can I prevent this? should I use semaphore and threads instead of Parallel? Or there is a better way?
public void Start() {
Parallel.Invoke(() => { crawl(url) } );
}
crawl(string url) {
var response = getresponse(url);
Parallel.foreach(response.links, ParallelOption, link => {
crawl(link);
});
}
Question 3. Notify when all Jobs (and nested jobs) finished.
And my last question is how can I understand when all my jobs has finished?
I'd suggest looking at Microsoft's Reactive Framework for this. You can write your
Crawl
function like this:Then to call it try this:
Done. It handles all the threading for you. Just NuGet "System.Reactive".