Skip to content

Instantly share code, notes, and snippets.

@udaken
Created July 19, 2016 14:41
Show Gist options
  • Save udaken/5b916c6538b94475db6e2eb7c2c84687 to your computer and use it in GitHub Desktop.
Save udaken/5b916c6538b94475db6e2eb7c2c84687 to your computer and use it in GitHub Desktop.
C# Tasks

タスクの作成(実行せず)

var task = new Task(() => Thread.Sleep(1000));

タスクの作成と実行

var task = Task.Run(() => Thread.Sleep(1000));

タスクの実行

タスクをスレッドプールで実行する

task.Start();

タスクを現在ので実行する

task.Start();

タスクの完了を待つ

スレッドプールで実行しているタスクの完了を現在のスレッドコンテキストで待つ

task.Wait();

完了済みタスクの作成

var task = Task.FromResult(1);
var task = Task.CompletedTask;

同時実行数を指定してForEach

Parallel.ForEach(Enumerable.Range(1, 100), new ParallelOptions { MaxDegreeOfParallelism = 4 }, i =>
{
    Thread.Sleep(1000);
});

複数のタスクを待機するタスクを作成

var combinedTask = Task.WhenAll(task1, task2, task3);

タスクのキャンセル

var cancellationTokenSource = new CancellationTokenSource();
var tocken = cancellationTokenSource.Token;

var task = Task.Run(() =>
{
    Thread.Sleep(1000);
}, tocken).ContinueWith(t =>
{
    if (t.IsCanceled)
    {
        Console.WriteLine("Canceled.");
    }
});

cancellationTokenSource.Cancel(true);

ForEachAsync

http://neue.cc/2014/03/14_448.html

public static class EnumerableExtensions
{
    public static async Task ForEachAsync<T>(this IEnumerable<T> source, Func<T, Task> action, int concurrency, CancellationToken cancellationToken = default(CancellationToken), bool configureAwait = false)
    {
        if (source == null) throw new ArgumentNullException("source");
        if (action == null) throw new ArgumentNullException("action");
        if (concurrency <= 0) throw new ArgumentOutOfRangeException("concurrencyは1以上の必要があります");
 
        using (var semaphore = new SemaphoreSlim(initialCount: concurrency, maxCount: concurrency))
        {
            var exceptionCount = 0;
            var tasks = new List<Task>();
 
            foreach (var item in source)
            {
                if (exceptionCount > 0) break;
                cancellationToken.ThrowIfCancellationRequested();
 
                await semaphore.WaitAsync(cancellationToken).ConfigureAwait(configureAwait);
                var task = action(item).ContinueWith(t =>
                {
                    semaphore.Release();
 
                    if (t.IsFaulted)
                    {
                        Interlocked.Increment(ref exceptionCount);
                        throw t.Exception;
                    }
                });
                tasks.Add(task);
            }
 
            await Task.WhenAll(tasks.ToArray()).ConfigureAwait(configureAwait);
        }
    }
}

いろいろなTaskScheduler

ParallelExtensionsExtras[http://blogs.msdn.com/b/pfxteam/archive/2010/04/04/9990342.aspx]

  • IOCompletionPortTaskScheduler.cs
  • IOTaskScheduler.cs
  • LimitedConcurrencyLevelTaskScheduler.cs
  • OrderedTaskScheduler.cs
  • QueuedTaskScheduler.cs
  • ReprioritizableTaskScheduler.cs
  • RoundRobinTaskScheduler.cs
  • StaTaskScheduler.cs
  • SynchronizationContextTaskScheduler.cs
  • ThreadPerTaskkScheduler.cs
  • WorkStealingTaskScheduler.cs
  • ConcurrentExclusiveInterleave.cs
  • CurrentThreadTaskScheduler.cs

COMアパートメントを指定して、独立したワーカースレッドを実行する

http://www.kekyo.net/2015/06/04/4735

public static Task<TResult> RunEx<TResult>(
    Func<TResult> action,
    ApartmentState state = ApartmentState.STA)
{
    // スレッド終了を通知するTaskCompletionSource
    var tcs = new TaskCompletionSource<TResult>();
 
    // ワーカースレッドを生成する
    var thread = new Thread(new ThreadStart(() =>
        {
            try
            {
                // 処理本体を実行して、戻り値を得る
                var result = action();
 
                // Taskに終了を通知
                tcs.SetResult(result);
            }
            catch (Exception ex)
            {
                // 例外をTaskに通知
                tcs.SetException(ex);
            }
        }));
    thread.SetApartmentState(state);
    thread.Start();
 
    // Task<TResult>を返す
    return tcs.Task;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment