タグ付けされた質問 「task-parallel-library」

Task Parallel Libraryは、.NET 4以降、.NET Frameworkの一部です。これは、開発者が非同期アプリケーションをプログラミングできるようにするAPIのセットです。

6
CancellationTokenのデフォルトパラメータ
追加したい非同期コードがありCancellationTokenます。ただし、これが不要な実装はたくさんあるので、デフォルトのパラメータを使用したいと思いますCancellationToken.None。しかしながら、 Task<x> DoStuff(...., CancellationToken ct = null) 収量 タイプ「System.Threading.CancellationToken」への標準的な変換がないため、タイプ ''の値はデフォルトパラメータとして使用できません そして Task<x> DoStuff(...., CancellationToken ct = CancellationToken.None) 'ct'のデフォルトのパラメーター値はコンパイル時の定数でなければなりません のデフォルト値を設定する方法はありますCancellationTokenか?

5
デッドロックを引き起こす非同期/待機の例
c#のasync/ awaitキーワードを使用した非同期プログラミングのベストプラクティスに出くわしました(c#5.0は初めてです)。 与えられたアドバイスの1つは次のとおりです。 安定性:同期コンテキストを知る ...一部の同期コンテキストは非再入可能で、シングルスレッドです。つまり、コンテキスト内で一度に実行できる作業単位は1つだけです。この例は、Windows UIスレッドまたはASP.NET要求コンテキストです。これらのシングルスレッド同期コンテキストでは、自分でデッドロックするのは簡単です。シングルスレッドコンテキストからタスクを生成し、そのコンテキストでそのタスクを待つ場合、待機中のコードがバックグラウンドタスクをブロックしている可能性があります。 public ActionResult ActionAsync() { // DEADLOCK: this blocks on the async task var data = GetDataAsync().Result; return View(data); } private async Task<string> GetDataAsync() { // a very simple async method var result = await MyWebService.GetDataAsync(); return result.ToString(); } 自分で分解しようとすると、メインスレッドはで新しいスレッドにスポーンしMyWebService.GetDataAsync();ますが、メインスレッドはそこで待機しているので、で結果を待機しGetDataAsync().Resultます。一方、データの準備ができていると言います。メインスレッドが継続ロジックを継続せず、継続結果の文字列を返すのはなぜGetDataAsync()ですか? 上記の例でデッドロックが発生する理由を誰かが説明してもらえますか?私は問題が何であるかについて完全に無知です...

3
SemaphoreSlimの使用法を理解する必要があります
これが私が持っているコードですが、何SemaphoreSlimをしているのかわかりません。 async Task WorkerMainAsync() { SemaphoreSlim ss = new SemaphoreSlim(10); List<Task> trackedTasks = new List<Task>(); while (DoMore()) { await ss.WaitAsync(); trackedTasks.Add(Task.Run(() => { DoPollingThenWorkAsync(); ss.Release(); })); } await Task.WhenAll(trackedTasks); } void DoPollingThenWorkAsync() { var msg = Poll(); if (msg != null) { Thread.Sleep(2000); // process the long running CPU-bound job …

3
終わりのないタスクを実装するための適切な方法。(タイマーvsタスク)
そのため、私のアプリは、アプリが実行されているか、キャンセルが要求されている限り、ほぼ連続的に(実行ごとに10秒程度の休止を置いて)アクションを実行する必要があります。必要な作業には、最大30秒かかる可能性があります。 System.Timers.Timerを使用し、AutoResetを使用して、前の「ティック」が完了する前にアクションが実行されないようにすることをお勧めします。 または、キャンセルトークンを使用してLongRunningモードで一般的なタスクを使用し、呼び出しの間に10秒間のThread.Sleepを使用してアクションを実行するアクションを呼び出す通常の無限whileループを含める必要がありますか?非同期/待機モデルについては、作業からの戻り値がないため、ここが適切かどうかはわかりません。 CancellationTokenSource wtoken; Task task; void StopWork() { wtoken.Cancel(); try { task.Wait(); } catch(AggregateException) { } } void StartWork() { wtoken = new CancellationTokenSource(); task = Task.Factory.StartNew(() => { while (true) { wtoken.Token.ThrowIfCancellationRequested(); DoWork(); Thread.Sleep(10000); } }, wtoken, TaskCreationOptions.LongRunning); } void DoWork() { // Some work that takes …

7
System.Threading.Timerのタスクベースの置き換えはありますか?
.Net 4.0のタスクは初めてですが、定期的なタスクなど、タスクベースのタイマーの交換またはタイマーの実装だと思っていたものを見つけることができませんでした。そんなことありますか? 更新 私は自分のニーズに対するソリューションであると考えるものを思い付きました。それは、すべてのCancellationTokenを利用して子タスクで「タイマー」機能をタスク内にラップし、タスクを返して次のタスクステップに参加できるようにすることです。 public static Task StartPeriodicTask(Action action, int intervalInMilliseconds, int delayInMilliseconds, CancellationToken cancelToken) { Action wrapperAction = () => { if (cancelToken.IsCancellationRequested) { return; } action(); }; Action mainAction = () => { TaskCreationOptions attachedToParent = TaskCreationOptions.AttachedToParent; if (cancelToken.IsCancellationRequested) { return; } if (delayInMilliseconds > 0) Thread.Sleep(delayInMilliseconds); while …

7
prevTask.Wait()は、(タスクライブラリの)ContinueWithで使用することをお勧めしますか?
それで、最近、私は.ContinueWith for Tasksをどのように使用しているかが、適切な使用方法ではないと言われました。私はインターネットでこれの証拠をまだ見つけていないので、皆さんに尋ねて、答えが何であるかを確認します。これが.ContinueWithの使用例です。 public Task DoSomething() { return Task.Factory.StartNew(() => { Console.WriteLine("Step 1"); }) .ContinueWith((prevTask) => { Console.WriteLine("Step 2"); }) .ContinueWith((prevTask) => { Console.WriteLine("Step 3"); }); } これは簡単な例であり、非常に高速に実行されることを知っていますが、各タスクがより長い操作を実行すると仮定します。だから、私が言われたことは、.ContinueWithでは、prevTask.Wait();と言う必要があるということです。それ以外の場合は、前のタスクが完了する前に作業を行うことができます。それは可能ですか?2つ目と3つ目のタスクは、前のタスクが終了して初めて実行されると想定しました。 コードの書き方を教えられた: public Task DoSomething() { return Task.Factory.StartNew(() => { Console.WriteLine("Step 1"); }) .ContinueWith((prevTask) => { prevTask.Wait(); Console.WriteLine("Step 2"); }) .ContinueWith((prevTask) => { …

7
Task.Run with Parameter(s)?
私はマルチタスクネットワークプロジェクトに取り組んでおり、は初めてですThreading.Tasks。シンプルなものを実装しましたが、Task.Factory.StartNew()どうすればそれができるのでしょうか。Task.Run()でしょうか? 基本的なコードは次のとおりです。 Task.Factory.StartNew(new Action<object>( (x) => { // Do something with 'x' }), rawData); オブジェクトブラウザを調べましSystem.Threading.Tasks.Taskたが、同様のパラメータが見つかりませんでした。パラメータを取るものだけがあり、タイプはありません。Action<T>Actionvoid そこ似唯一の2つのことは、次のとおりstatic Task Run(Action action)とstatic Task Run(Func<Task> function)が、両方とポストパラメータ(複数可)することはできません。 はい、私はそれのための簡単な拡張メソッドを作成できることを知っていますが、私の主な質問は、それを1行で書くことができるTask.Run()かどうかです。

4
非同期BlockingCollection <T>のようなものはありますか?
非同期awaitの結果を確認したいBlockingCollection&lt;T&gt;.Take()ので、スレッドをブロックしません。このようなものを探しています: var item = await blockingCollection.TakeAsync(); 私はこれができることを知っています: var item = await Task.Run(() =&gt; blockingCollection.Take()); しかし、ThreadPool代わりに(の)別のスレッドがブロックされるため、それはアイデア全体をやや殺します。 代替手段はありますか?

2
BackgroundWorkerのタスク並列ライブラリの置き換え?
タスク並列ライブラリには、BackgroundWorkerクラスの置き換えまたは改善と見なされるものがありますか? ウィザードスタイルのUIを備えたWinFormsアプリケーションがあり、長時間実行されるタスクを実行します。標準のプログレスバーと操作をキャンセルする機能を備えたレスポンシブUIを使用できるようにしたいと考えています。以前にBackgroundWorkerでこれを実行しましたが、代わりに使用できるTPLパターンがいくつかあるかどうか疑問に思っています。

6
タスクの同期継続を防ぐにはどうすればよいですか?
にTask基づいて、リクエストへの保留中の応答にベースのAPIを提供するライブラリ(ソケットネットワーク)コードがありますTaskCompletionSource&lt;T&gt;。ただし、同期継続を防ぐことは不可能であるように思われるという点で、TPLには煩わしさがあります。私はなりたいと行うことができるようにすることのいずれかです: TaskCompletionSource&lt;T&gt;発信者が、、TaskContinuationOptions.ExecuteSynchronouslyまたはで接続することを許可してはならないことを伝えます 代わりにプールを使用して、無視する必要があることを指定する方法で結果(SetResult/ TrySetResult)を設定しTaskContinuationOptions.ExecuteSynchronouslyます 具体的には、私が抱えている問題は、受信データが専用のリーダーによって処理されており、発信者が接続できる場合TaskContinuationOptions.ExecuteSynchronously、リーダーをストールさせる可能性があることです(これはそれらだけに影響を与えるだけではありません)。以前、私はかどうかを検出することをいくつかの牛車でこれを回避働いている任意の継続が存在し、それらがある場合、それはへの完了を押してThreadPool完了が処理されませうとして、発信者が、自分の仕事のキューを飽和している場合は、しかし、これは重大な影響を持っていますタイムリーに。彼らが使用しているTask.Wait()(または同様の)場合、彼らは本質的に彼ら自身をデッドロックさせます。同様に、これが、リーダーがワーカーを使用するのではなく、専用のスレッドを使用している理由です。 そう; TPLチームを悩ませる前に:オプションがありませんか? キーポイント: 外部の発信者が自分のスレッドを乗っ取れるようにしたくない ThreadPoolプールが飽和状態のときに機能する必要があるため、実装として使用することはできません 以下の例では、出力が生成されます(順序はタイミングによって異なる場合があります)。 Continuation on: Main thread Press [return] Continuation on: Thread pool 問題は、ランダムな呼び出し元が「メインスレッド」で継続を取得できたという事実です。実際のコードでは、これはプライマリリーダーを中断します。悪いこと! コード: using System; using System.Threading; using System.Threading.Tasks; static class Program { static void Identify() { var thread = Thread.CurrentThread; string name = thread.IsThreadPoolThread ? "Thread pool" : thread.Name; …

2
タスクで例外をキャッチするための最良の方法は何ですか?
を使用するとSystem.Threading.Tasks.Task&lt;TResult&gt;、スローされる可能性のある例外を管理する必要があります。私はそれを行うための最良の方法を探しています。これまでのところ、の呼び出し内でキャッチされなかったすべての例外を管理する基本クラスを作成しました.ContinueWith(...) それを行うより良い方法があるかどうか疑問に思います。またはそれがそれをする良い方法であるとしても。 public class BaseClass { protected void ExecuteIfTaskIsNotFaulted&lt;T&gt;(Task&lt;T&gt; e, Action action) { if (!e.IsFaulted) { action(); } else { Dispatcher.CurrentDispatcher.BeginInvoke(new Action(() =&gt; { /* I display a window explaining the error in the GUI * and I log the error. */ this.Handle.Error(e.Exception); })); } } } public class ChildClass …

3
Task.WhenAllの継続が同期的に実行されるのはなぜですか?
Task.WhenAll.NET Core 3.0で実行しているときに、私はメソッドについて奇妙な観察をしました。単純なTask.Delayタスクを単一の引数としてに渡しましたTask.WhenAllが、ラップされたタスクは元のタスクと同じように動作するはずです。しかし、そうではありません。元のタスクの継続は非同期で実行され(これは望ましい)、複数のTask.WhenAll(task)ラッパーの継続は1つずつ同期して実行されます(これは望ましくありません)。 ここでデモこの動作のは。4つのワーカータスクが同じTask.Delayタスクが完了するのを待ってから、重い計算(でシミュレートThread.Sleep)を続行します。 var task = Task.Delay(500); var workers = Enumerable.Range(1, 4).Select(async x =&gt; { Console.WriteLine($"{DateTime.Now:HH:mm:ss.fff}" + $" [{Thread.CurrentThread.ManagedThreadId}] Worker{x} before await"); await task; //await Task.WhenAll(task); Console.WriteLine($"{DateTime.Now:HH:mm:ss.fff}" + $" [{Thread.CurrentThread.ManagedThreadId}] Worker{x} after await"); Thread.Sleep(1000); // Simulate some heavy CPU-bound computation }).ToArray(); Task.WaitAll(workers); これが出力です。4つの継続は、異なるスレッドで(並列に)期待どおりに実行されています。 05:23:25.511 [1] Worker1 before await 05:23:25.542 …
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.