6

.net 4.5 では、非同期メソッドを簡単に呼び出すことができる await, async キーワードがあることを認識しています。私は現在、C# 4.0 で非同期呼び出しを行う方法を研究しています。私がしたい例は、データグリッドがデータバインドされている場所で非同期呼び出しを行うことです。

いくつかのリンクを提供していただければ、本当に感謝しています。

4

3 に答える 3

7

Tasks の使用をご覧ください。これは .Net 4 で利用可能であり、役立つはずです。簡単な例は次のようになります。

public void MainFlow()
{
   Task taskWork = Task.Factory.StartNew(new Action(DoWork));
   //Do other work
   //Then wait for thread finish
   taskWork.Wait();
}


private void DoWork()
{
   //Do work
}

詳しくはこちらをご覧ください

于 2012-11-07T09:05:03.663 に答える
1

非同期操作を実行するためのツール クラスを作成しました。

これらのメソッドが実際に行うこと: アクションを非同期的に実行し、同期コンテキストに従って完了の実行を通知します。

これをTPLのラッパーとして作成し、長時間実行される操作を呼び出すときにWPFで簡単に使用できるようにしました。このクラスには、放棄するだけでなく、キャンセルできるアクションの類似物もあります。

public static class AsyncExecutor
    {
        public static CancellationTokenSource ExecuteBlockingOperation(Action action, Action completition, Action<AggregateException> onException)
        {
            if (action == null)
                throw new ArgumentNullException("action");

            if (completition == null)
                throw new ArgumentNullException("completition");

            var cts = new CancellationTokenSource();
            var token = cts.Token;

            var scheduler = TaskScheduler.FromCurrentSynchronizationContext();

            var task = new Task(action, TaskCreationOptions.LongRunning);
            task.ContinueWith(asyncPartTask => onException(asyncPartTask.Exception), CancellationToken.None, TaskContinuationOptions.OnlyOnFaulted, scheduler);
            task.ContinueWith(asyncPart =>
                                  {
                                      if (!token.IsCancellationRequested)
                                          completition();
                                  },
                              CancellationToken.None, TaskContinuationOptions.OnlyOnRanToCompletion, scheduler);
            task.Start();

            return cts;

        }

        public static CancellationTokenSource ExecuteBlockingOperation<TIn>(Action<TIn> action, TIn parameter, Action<TIn> completition, Action<AggregateException, TIn> onException)
        {
            if (action == null)
                throw new ArgumentNullException("action");

            if (completition == null)
                throw new ArgumentNullException("completition");

            var cts = new CancellationTokenSource();
            var token = cts.Token;

            var scheduler = TaskScheduler.FromCurrentSynchronizationContext();

            var task = new Task(() => action(parameter), TaskCreationOptions.LongRunning);
            task.ContinueWith(asyncPartTask => onException(asyncPartTask.Exception, parameter), CancellationToken.None, TaskContinuationOptions.OnlyOnFaulted, scheduler);
            task.ContinueWith(asyncPart =>
                                  {
                                      if (!token.IsCancellationRequested)
                                          completition(parameter);
                                  },
                              CancellationToken.None, TaskContinuationOptions.OnlyOnRanToCompletion, scheduler);
            task.Start();

            return cts;

        }

        public static CancellationTokenSource ExecuteBlockingOperation<TOut>(Func<TOut> func, Action<TOut> completition, Action<AggregateException> onException)
        {
            if (func == null)
                throw new ArgumentNullException("func");

            if (completition == null)
                throw new ArgumentNullException("completition");

            var cts = new CancellationTokenSource();
            var token = cts.Token;

            var scheduler = TaskScheduler.FromCurrentSynchronizationContext();

            var task = new Task<TOut>(func, TaskCreationOptions.LongRunning);
            task.ContinueWith(asyncPartTask => onException(asyncPartTask.Exception), CancellationToken.None, TaskContinuationOptions.OnlyOnFaulted, scheduler);
            task.ContinueWith(asyncPart =>
                                  {
                                      if (!token.IsCancellationRequested)
                                          completition(asyncPart.Result);
                                  },
                              CancellationToken.None, TaskContinuationOptions.OnlyOnRanToCompletion, scheduler);
            task.Start();

            return cts;

        }

        public static CancellationTokenSource ExecuteBlockingOperation<TIn, TOut>(Func<TIn, TOut> func, TIn parameter, Action<TOut, TIn> completition, Action<AggregateException, TIn> onException)
        {
            if (func == null)
                throw new ArgumentNullException("func");

            if (completition == null)
                throw new ArgumentNullException("completition");

            var cts = new CancellationTokenSource();
            var token = cts.Token;

            var scheduler = TaskScheduler.FromCurrentSynchronizationContext();

            var task = new Task<TOut>(() => func(parameter), TaskCreationOptions.LongRunning);
            task.ContinueWith(asyncPartTask => onException(asyncPartTask.Exception, parameter), CancellationToken.None, TaskContinuationOptions.OnlyOnFaulted, scheduler);
            task.ContinueWith(asyncPart =>
            {
                if (!token.IsCancellationRequested)
                    completition(asyncPart.Result, parameter);
            },
                              CancellationToken.None, TaskContinuationOptions.OnlyOnRanToCompletion, scheduler);
            task.Start();

            return cts;
        }

        public static CancellationTokenSource ExecuteBlockingOperation<TIn, TOut>(Func<TIn, TOut> func, TIn parameter, Action<TOut> completition, Action<AggregateException, TIn> onException)
        {
            if (func == null)
                throw new ArgumentNullException("func");

            if (completition == null)
                throw new ArgumentNullException("completition");

            var cts = new CancellationTokenSource();
            var token = cts.Token;

            var scheduler = TaskScheduler.FromCurrentSynchronizationContext();

            var task = new Task<TOut>(() => func(parameter), TaskCreationOptions.LongRunning);
            task.ContinueWith(asyncPartTask => onException(asyncPartTask.Exception, parameter), CancellationToken.None, TaskContinuationOptions.OnlyOnFaulted, scheduler);
            task.ContinueWith(asyncPart =>
            {
                if (!token.IsCancellationRequested)
                    completition(asyncPart.Result);
            },
                              CancellationToken.None, TaskContinuationOptions.OnlyOnRanToCompletion, scheduler);
            task.Start();

            return cts;
        }

        public static CancellationTokenSource ExecuteBlockingOperation<TIn, TOut>(Func<TIn, TOut> func, TIn parameter, Action<TIn> completition, Action<AggregateException, TIn> onException)
        {
            if (func == null)
                throw new ArgumentNullException("func");

            if (completition == null)
                throw new ArgumentNullException("completition");

            var cts = new CancellationTokenSource();
            var token = cts.Token;

            var scheduler = TaskScheduler.FromCurrentSynchronizationContext();

            var task = new Task<TOut>(() => func(parameter), TaskCreationOptions.LongRunning);
            task.ContinueWith(asyncPartTask => onException(asyncPartTask.Exception, parameter), CancellationToken.None, TaskContinuationOptions.OnlyOnFaulted, scheduler);
            task.ContinueWith(asyncPart =>
            {
                if (!token.IsCancellationRequested)
                    completition(parameter);
            },
                              CancellationToken.None, TaskContinuationOptions.OnlyOnRanToCompletion, scheduler);
            task.Start();

            return cts;
        }

        public static CancellationTokenSource ExecuteBlockingOperation<TIn, TOut>(Func<TIn, TOut> func, TIn parameter, Action completition, Action<AggregateException, TIn> onException)
        {
            if (func == null)
                throw new ArgumentNullException("func");

            if (completition == null)
                throw new ArgumentNullException("completition");

            var cts = new CancellationTokenSource();
            var token = cts.Token;

            var scheduler = TaskScheduler.FromCurrentSynchronizationContext();

            var task = new Task<TOut>(() => func(parameter), TaskCreationOptions.LongRunning);
            task.ContinueWith(asyncPartTask => onException(asyncPartTask.Exception, parameter), CancellationToken.None, TaskContinuationOptions.OnlyOnFaulted, scheduler);
            task.ContinueWith(asyncPart =>
            {
                if (!token.IsCancellationRequested)
                    completition();
            },
                              CancellationToken.None, TaskContinuationOptions.OnlyOnRanToCompletion, scheduler);
            task.Start();

            return cts;
        }

        public static CancellationTokenSource ExecuteBlockingOperation<TIn, TOut>(Func<TIn, TOut> func, TIn parameter, Action<TIn> completition, Action<AggregateException> onException)
        {
            if (func == null)
                throw new ArgumentNullException("func");

            if (completition == null)
                throw new ArgumentNullException("completition");

            var cts = new CancellationTokenSource();
            var token = cts.Token;

            var scheduler = TaskScheduler.FromCurrentSynchronizationContext();

            var task = new Task<TOut>(() => func(parameter), TaskCreationOptions.LongRunning);
            task.ContinueWith(asyncPartTask => onException(asyncPartTask.Exception), CancellationToken.None, TaskContinuationOptions.OnlyOnFaulted, scheduler);
            task.ContinueWith(asyncPart =>
            {
                if (!token.IsCancellationRequested)
                    completition(parameter);
            },
                              CancellationToken.None, TaskContinuationOptions.OnlyOnRanToCompletion, scheduler);
            task.Start();

            return cts;
        }

        public static CancellationTokenSource ExecuteBlockingOperation<TIn, TOut>(Func<TIn, TOut> func, TIn parameter, Action<TOut, TIn> completition, Action<AggregateException> onException)
        {
            if (func == null)
                throw new ArgumentNullException("func");

            if (completition == null)
                throw new ArgumentNullException("completition");

            var cts = new CancellationTokenSource();
            var token = cts.Token;

            var scheduler = TaskScheduler.FromCurrentSynchronizationContext();

            var task = new Task<TOut>(() => func(parameter), TaskCreationOptions.LongRunning);
            task.ContinueWith(asyncPartTask => onException(asyncPartTask.Exception), CancellationToken.None, TaskContinuationOptions.OnlyOnFaulted, scheduler);
            task.ContinueWith(asyncPart =>
            {
                if (!token.IsCancellationRequested)
                    completition(asyncPart.Result, parameter);
            },
                              CancellationToken.None, TaskContinuationOptions.OnlyOnRanToCompletion, scheduler);
            task.Start();

            return cts;
        }

        public static CancellationTokenSource ExecuteBlockingOperation<TIn, TOut>(Func<TIn, TOut> func, TIn parameter, Action<TOut> completition, Action<AggregateException> onException)
        {
            if (func == null)
                throw new ArgumentNullException("func");

            if (completition == null)
                throw new ArgumentNullException("completition");

            var cts = new CancellationTokenSource();
            var token = cts.Token;

            var scheduler = TaskScheduler.FromCurrentSynchronizationContext();

            var task = new Task<TOut>(() => func(parameter), TaskCreationOptions.LongRunning);
            task.ContinueWith(asyncPartTask => onException(asyncPartTask.Exception), CancellationToken.None, TaskContinuationOptions.OnlyOnFaulted, scheduler);
            task.ContinueWith(asyncPart =>
            {
                if (!token.IsCancellationRequested)
                    completition(asyncPart.Result);
            },
                              CancellationToken.None, TaskContinuationOptions.OnlyOnRanToCompletion, scheduler);
            task.Start();

            return cts;
        }

        public static CancellationTokenSource ExecuteBlockingOperation<TIn, TOut>(Func<TIn, TOut> func, TIn parameter, Action completition, Action<AggregateException> onException)
        {
            if (func == null)
                throw new ArgumentNullException("func");

            if (completition == null)
                throw new ArgumentNullException("completition");

            var cts = new CancellationTokenSource();
            var token = cts.Token;

            var scheduler = TaskScheduler.FromCurrentSynchronizationContext();

            var task = new Task<TOut>(() => func(parameter), TaskCreationOptions.LongRunning);
            task.ContinueWith(asyncPartTask => onException(asyncPartTask.Exception), CancellationToken.None, TaskContinuationOptions.OnlyOnFaulted, scheduler);
            task.ContinueWith(asyncPart =>
            {
                if (!token.IsCancellationRequested)
                    completition();
            },
                              CancellationToken.None, TaskContinuationOptions.OnlyOnRanToCompletion, scheduler);
            task.Start();

            return cts;
        }

        public static void ExecuteBlockingOperation(Action action, Action completition, Func<bool> shouldComplete, Action<AggregateException> onException)
        {
            if (action == null)
                throw new ArgumentNullException("action");

            if (completition == null)
                throw new ArgumentNullException("completition");

            var scheduler = TaskScheduler.FromCurrentSynchronizationContext();

            var task = new Task(action, TaskCreationOptions.LongRunning);
            task.ContinueWith(asyncPartTask => onException(asyncPartTask.Exception), CancellationToken.None, TaskContinuationOptions.OnlyOnFaulted, scheduler);
            task.ContinueWith(asyncPart =>
                                  {
                                      if (shouldComplete == null || shouldComplete())
                                          completition();
                                  },
                              CancellationToken.None, TaskContinuationOptions.OnlyOnRanToCompletion, scheduler);
            task.Start();
        }

        public static void ExecuteBlockingOperation<TIn>(Action<TIn> action, TIn parameter, Action<TIn> completition, Predicate<TIn> shouldComplete, Action<AggregateException, TIn> onException)
        {
            if (action == null)
                throw new ArgumentNullException("action");

            if (completition == null)
                throw new ArgumentNullException("completition");

            var scheduler = TaskScheduler.FromCurrentSynchronizationContext();

            var task = new Task(() => action(parameter), TaskCreationOptions.LongRunning);
            task.ContinueWith(asyncPartTask => onException(asyncPartTask.Exception, parameter), CancellationToken.None, TaskContinuationOptions.OnlyOnFaulted, scheduler);
            task.ContinueWith(asyncPart =>
                                  {
                                      if (shouldComplete == null || shouldComplete(parameter))
                                          completition(parameter);
                                  },
                              CancellationToken.None, TaskContinuationOptions.OnlyOnRanToCompletion, scheduler);
            task.Start();
        }

        public static void ExecuteBlockingOperation<TOut>(Func<TOut> func, Action<TOut> completition, Predicate<TOut> shoudComplete, Action<AggregateException> onException)
        {
            if (func == null)
                throw new ArgumentNullException("func");

            if (completition == null)
                throw new ArgumentNullException("completition");

            var scheduler = TaskScheduler.FromCurrentSynchronizationContext();

            var task = new Task<TOut>(func, TaskCreationOptions.LongRunning);
            task.ContinueWith(asyncPartTask => onException(asyncPartTask.Exception), CancellationToken.None, TaskContinuationOptions.OnlyOnFaulted, scheduler);
            task.ContinueWith(asyncPartTask =>
                                  {
                                      if (shoudComplete == null || shoudComplete(asyncPartTask.Result))
                                          completition(asyncPartTask.Result);
                                  },
                              CancellationToken.None, TaskContinuationOptions.OnlyOnRanToCompletion, scheduler);
            task.Start();
        }

        public static void ExecuteBlockingOperation<TIn, TOut>(Func<TIn, TOut> func, TIn parameter, Action<TOut, TIn> completition, Func<TOut, TIn, bool> shouldComplete, Action<AggregateException, TIn> onException)
        {
            if (func == null)
                throw new ArgumentNullException("func");

            if (completition == null)
                throw new ArgumentNullException("completition");

            var scheduler = TaskScheduler.FromCurrentSynchronizationContext();

            var task = new Task<TOut>(() => func(parameter), TaskCreationOptions.LongRunning);
            task.ContinueWith(asyncPartTask => onException(asyncPartTask.Exception, parameter), CancellationToken.None, TaskContinuationOptions.OnlyOnFaulted, scheduler); // on Exception
            task.ContinueWith(asyncPart =>
                                  {
                                      if (shouldComplete == null || shouldComplete(asyncPart.Result, parameter))
                                          completition(asyncPart.Result, parameter);
                                  },
                              CancellationToken.None, TaskContinuationOptions.OnlyOnRanToCompletion, scheduler);
            task.Start();
        }            
    }
于 2012-11-07T10:55:16.570 に答える
1

タスクが完了すると、基本的にアクションを実行する Task.ContinueWith を使用します。

役に立つかもしれないいくつかの例:

http://msdn.microsoft.com/en-us/library/dd784422.aspx

于 2012-11-07T09:07:46.317 に答える