質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.50%
C#

C#はマルチパラダイムプログラミング言語の1つで、命令形・宣言型・関数型・ジェネリック型・コンポーネント指向・オブジェクティブ指向のプログラミング開発すべてに対応しています。

.NET Framework

.NET Framework は、Microsoft Windowsのオペレーティングシステムのために開発されたソフトウェア開発環境/実行環境です。多くのプログラミング言語をサポートしています。

Q&A

4回答

13053閲覧

Task.Run()の同時実行数制限

退会済みユーザー

退会済みユーザー

総合スコア0

C#

C#はマルチパラダイムプログラミング言語の1つで、命令形・宣言型・関数型・ジェネリック型・コンポーネント指向・オブジェクティブ指向のプログラミング開発すべてに対応しています。

.NET Framework

.NET Framework は、Microsoft Windowsのオペレーティングシステムのために開発されたソフトウェア開発環境/実行環境です。多くのプログラミング言語をサポートしています。

0グッド

1クリップ

投稿2019/02/20 07:32

編集2022/01/12 10:55
private void button1_Click(object sender, EventArgs e) { int iIdx = 0; Task.Run(() => { for (;;) { iIdx++; Task.Run(() => { My_Func(iIdx); }); Console.WriteLine("処理1"); Console.WriteLine("処理2"); Thread.Sleep(10); } }); } void My_Func(int iIdx) { Console.WriteLine(iIdx.ToString()); Thread.Sleep(20000); }

上のコードで質問です。

やりたいことは、別スレッド(スレッドA)で無限ループさせて My_Func()はまた別のスレッド(スレッドB)で実行します。
「処理1」, 「処理2」は毎回実行。My_Func()は処理が終わるまで新しく実行しない。

自分で考えたのが、スレッドBの同時実行回数を制限すればいいのかなと思ったのですが、そのやり方が分かりません。
どこを修正、追加したらいいでしょうか。

よろしくお願いいたします。

追記
実現実行順序は

以下をループ

My_Func()が実行中ではなかったら
My_Func()を別スレッドで実行。

処理1

処理2
→ → → ↑

実行結果は
1
処理1
処理2
処理1
処理2
処理1
処理2
処理1
処理2
99999 ← ここの数字はなんでもいい
処理1
処理2
処理1
処理2
処理1
処理2
処理1
処理2
99999 ← ここの数字はなんでもいい

こうなってほしいです。
説明が下手ですみません。

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

y_waiwai

2019/02/20 07:36

なんのために同時実行回数を制限するんでしょう。目的が見えません
退会済みユーザー

退会済みユーザー

2019/02/20 07:40

すみません。My_Func()が終了するまでは、その場所を通っても新しくスレッドを作ったり、My_Func()を実行し欲しくありません。「処理1」「処理2」は通るたびに実行してほしいです。今回はただのテストで作ったプログラムなのですが本来はいろいろと困ることがあるので本番環境でする前にテストをしていたのですが初心者故、つまずいてしまい質問した次第でした。
guest

回答4

0

TaskScheduler Class
LimitedConcurrencyLevelTaskScheduler
(スレッドの数を制限するカスタム タスク スケジューラ)のサンプルがあります。
それを利用して

C#

1var scheduler = new LimitedConcurrencyLevelTaskScheduler(1); 2var factory = new TaskFactory(scheduler); 3 4int iIdx = 0; 5 6Task.Run(() => 7{ 8 for (; ; ) 9 { 10 iIdx++; 11 12 factory.StartNew(() => My_Func(iIdx)); 13 14 Console.WriteLine("処理1"); 15 Console.WriteLine("処理2"); 16 Thread.Sleep(10); 17 } 18});

投稿2019/02/20 08:57

hihijiji

総合スコア4150

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

0

private void button1_Click(object sender, EventArgs e) { int iIdx = 0; Task.Run(async () => { for (;;) { iIdx++; await My_Func(iIdx); Console.WriteLine("処理1"); Console.WriteLine("処理2"); await Task.Delay(10); } }); } SemaphoreSlim semaphore = new SemaphoreSlim(0, 1); async Task My_Func(int iIdx) { if (await semaphore.WaitAsync(0)) { Console.WriteLine(iIdx.ToString()); await Task.Delay(20000); semaphore.Release(); } }

こんな感じか。
どうやって止めるのだろう?とか素朴な疑問はあるけど。

追記

SemaphoreSlim を使えば解決じゃないかな
SemaphoreSlim を使って並列実行を制御する

投稿2019/02/20 07:40

編集2019/02/20 09:59
kiichi54321

総合スコア1984

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

退会済みユーザー

退会済みユーザー

2019/02/20 07:56

少し違いました...。 説明が下手ですみません。 追記したので、また回答していただけると助かります。
退会済みユーザー

退会済みユーザー

2019/02/20 09:17

あ、自分もそれ見てみたんですけどどうも使い方がわからなくて... よかったらそのコードに期待する処理ができるように回答してほしいです。 よろしくお願いいたします!!!!!
guest

0

こんにちは!
おそらく非同期でLockができればいいのだと思います。
AsyncLockが以下の記事で紹介されているので実装してみてください。
内容はkiichi54321さんが紹介しているSemaphoreSlimを使ったものです。

非同期:awaitを含むコードをロックするには?

投稿2019/02/26 10:38

mikupedia

総合スコア159

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

0

この質問におけるLoop()のように、My_Funcをループで特定の1つの処理を繰り返すクラスにすればいいんじゃないですかね?
(ボタンのハンドラがMy_Funcのループを制御するんじゃなくて、My_Funcを自身で1つのループを繰り返す実体にする)

投稿2019/02/20 08:30

papinianus

総合スコア12705

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

まだベストアンサーが選ばれていません

会員登録して回答してみよう

アカウントをお持ちの方は

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.50%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問