Make several asynchronous calls and do something when they are completed

I ran into this problem in several programming languages, and I was just wondering how best to deal with it.

I have three method calls that start asynchronously. Everyone has a callback. I want to do something only after completing all three callbacks.

What is the best way to code this? I usually get all of these public bool flags, and when you add more calls, the code becomes more confusing.

+3
source share
5 answers

#, , , WaitHandle.WaitAll. ManualResetEvent ( ) WaitAll. ManualResetEvent Set, . WaitAll , . #:

private void SpawnWorkers()
{
    ManualResetEvent[] resetEvents = new[] {
            new ManualResetEvent(false), 
            new ManualResetEvent(false)
        };

    // spawn the workers from a separate thread, so that
    // the WaitAll call does not block the main thread
    ThreadPool.QueueUserWorkItem((state) =>
    {
        ThreadPool.QueueUserWorkItem(Worker1, resetEvents[0]);
        ThreadPool.QueueUserWorkItem(Worker2, resetEvents[1]);
        WaitHandle.WaitAll(resetEvents);
        this.BeginInvoke(new Action(AllTasksAreDone));

    });
}
private void AllTasksAreDone()
{
    // OK, all are done, act accordingly
}

private void Worker1(object state)
{
    // do work, and then signal the waiting thread
    ((ManualResetEvent) state).Set();
}

private void Worker2(object state)
{
    // do work, and then signal the waiting thread
    ((ManualResetEvent)state).Set();
}

, AllTasksAreDone , , ... , .

+3

all:

  • , 0
+1
0

. , , asynch.

:



public struct FutureResult<T>
{
    public T Value;
    public Exception Error;
}
public class Future<T>
{
    public delegate R FutureDelegate<R>();
    public Future(FutureDelegate<T> del)
    {
        _del = del;
        _result = del.BeginInvoke(null, null);
    }
    private FutureDelegate<T> _del;
    private IAsyncResult _result;
    private T _persistedValue;
    private bool _hasValue = false;
    private T Value
    {
        get
        {
            if (!_hasValue)
            {
                if (!_result.IsCompleted)
                    _result.AsyncWaitHandle.WaitOne();
                _persistedValue = _del.EndInvoke(_result);
                _hasValue = true;
            }
            return _persistedValue;
        }
    }
    public static implicit operator T(Future<T> f)
    {
        return f.Value;
    }
}

>

:


        void SimulateDeadlock()
        {
            Future> deadlockFuture1 = new Future>(() =>
            {
                try
                {
                    new SystemData(ConfigurationManager.ConnectionStrings["DbConnectionString"].ConnectionString)
                        .SimulateDeadlock1(new DateTime(2000, 1, 1, 0, 0, 2));
                    return new FutureResult { Value = true };
                }
                catch (Exception ex)
                {
                    return new FutureResult { Value = false, Error = ex };
                }
            });
            Future> deadlockFuture2 = new Future>(() =>
            {
                try
                {
                    new SystemData(ConfigurationManager.ConnectionStrings["DbConnectionString"].ConnectionString)
                        .SimulateDeadlock2(new DateTime(2000, 1, 1, 0, 0, 2));
                    return new FutureResult { Value = true };
                }
                catch (Exception ex)
                {
                    return new FutureResult { Value = false, Error = ex };
                }
            });
            FutureResult result1 = deadlockFuture1;
            FutureResult result2 = deadlockFuture2;
            if (result1.Error != null)
            {
                if (result1.Error is SqlException && ((SqlException)result1.Error).Number == 1205)
                    Console.WriteLine("Deadlock!");
                else
                    Console.WriteLine(result1.Error.ToString());
            }
            else if (result2.Error != null)
            {
                if (result2.Error is SqlException && ((SqlException)result2.Error).Number == 1205)
                    Console.WriteLine("Deadlock!");
                else
                    Console.WriteLine(result2.Error.ToString());
            }
        }

0

, JavaScript, , Stackoverflow: javascript:

0

Source: https://habr.com/ru/post/1711187/


All Articles