views:

340

answers:

1
var arguments = new double[] { 1d, 2d, 3d };
var result = arguments.Select(arg => Math.Sqrt(arg));

Now imagine a asynchronous method instead of Math.Sqrt (i'm not sure the method below is a true async method, but it behaves approximately like one)

public void BeginSqrt(Action<double> callback, double argument)
{
    Thread.Sleep(100);
    callback(Math.Sqrt(argument));
}

There is no right way of calling such method without splitting the code. So let's synchronize this asynchronous method with AutoResetEvent. I created a helper class:

public class Synchronizer<T, TResult>
{
    AutoResetEvent _autoResetEvent = new AutoResetEvent(false);
    TResult _result;

    public TResult Execute(Action<Action<TResult>,T> beginMethod, T argument)
    {
        beginMethod(Callback, argument);
        _autoResetEvent.WaitOne();
        return _result;
    }

    void Callback(TResult result)
    {
        _result = result;
        _autoResetEvent.Set();
    }
}

With this class we can:

var synchronizer = new Synchronizer<double, double>();
var result = arguments.Select(arg => synchronizer.Execute(BeginSqrt, arg));

This solution I created in a few minutes while I was thinking about the problem. There is a native alternative to this? I am sure my solutions has bugs, since it misses some locks. There is a more proven library to do that?

+1  A: 

Using Parallel LINQ you can write:

var arguments = new double[] { 1d, 2d, 3d };
var result = arguments.AsParallel().Select(arg => Math.Sqrt(arg));

This would calculate the square root of each argument in parallel. Is that what you're trying to achieve?

dtb
your solution would yield a similar result to what I am trying to achieve in this specific case. But imagine that I was trying to use a true Async method like HttpWebRequest.BeginGetResponse. In this case your solution would do only 2 simultaneous requests in a dual core machine, while I am trying to achieve something like 30 simultaneous request.
Jader Dias
AFAIK the number of threads used by PLINQ is adjusted dynamically to the optimum of your machine: It's not fixed to the number of your processors/cores which would be silly.
dtb
You missed the point, please pay attention to the order of magnitude: 2 x 30. While some requests are outbound, new ones can begin.
Jader Dias
What exactly are you trying to do? Your code currently just executes `BeginSqrt` and waits for the callback to be called before executing the next `BeginSqrt`.
dtb
I am writing a new version of the question where it will make sense
Jader Dias
I rewrote this question completely and posted again at: http://stackoverflow.com/questions/1776667/how-to-get-the-maximum-outbound-requests-when-parellellizing-asynchronous-calls
Jader Dias