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

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

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

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

Unity

Unityは、Unity Technologiesが開発・販売している、IDEを内蔵するゲームエンジンです。主にC#を用いたプログラミングでコンテンツの開発が可能です。

Q&A

解決済

1回答

2508閲覧

async,awaitで、前の処理が終わるのを待ちたい

nankoko

総合スコア20

C#

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

Unity

Unityは、Unity Technologiesが開発・販売している、IDEを内蔵するゲームエンジンです。主にC#を用いたプログラミングでコンテンツの開発が可能です。

0グッド

0クリップ

投稿2020/11/17 11:12

編集2020/11/17 11:31

下のコードを実行した時に、
1 start
1 end
2 start
2 end
と表示されるようにしたいのですが、方法はあるでしょうか?
Main()の中身は変えないで、async,awaitは使いたいです。


using System;
using System.Threading.Tasks;

class A{
static void Main(){
B b = new B();
b.Print(1);
b.Print(2);
Console.ReadLine();
}
}

class B{
public async Task Print( int i){
Console.WriteLine(i + " start");
await Task.Delay( 4000);
Console.WriteLine(i + " end");
}
}

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

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

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

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

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

YAmaGNZ

2020/11/17 11:34

使用されているバージョンはC#7.0以前ですか?C#7.1以降ですか?
BluOxy

2020/11/17 11:37 編集

すれ違いで回答してしまいましたが…(この回答だと「Main()の中身は変えない」から外れる) async,awaitは使いたいとは、掲示されたコードにさらに追加するという意味ではないのでしょうか。
YAmaGNZ

2020/11/17 11:42

非同期Mainをご存じないのかMainをasyncとしてエラーとなるので方法を聞いたのかが判断できなかったので質問しました。
YAmaGNZ

2020/11/17 11:48

あぁ、Mainの中身を変えないって追加があったんですか。
nankoko

2020/11/17 13:34

すみません、追加で修正しました。 紛らわしくて申し訳ありません。
guest

回答1

0

ベストアンサー

async,awaitを使いたいです。

非同期 Main を使ってください。

C#

1using System; 2using System.Threading.Tasks; 3 4class A { 5 static async Task Main () { 6 B b = new B (); 7 await b.Print (1); 8 await b.Print (2); 9 Console.ReadLine (); 10 } 11} 12 13class B { 14 public async Task Print (int i) { 15 Console.WriteLine (i + " start"); 16 await Task.Delay (4000); 17 Console.WriteLine (i + " end"); 18 } 19}

BクラスにSemaphoreSlimなり使う方法

C#

1using System; 2using System.Threading.Tasks; 3 4class A { 5 static void Main () { 6 B b = new B (); 7 b.Print (1); 8 b.Print (2); 9 Console.ReadLine (); 10 } 11} 12 13class B { 14 private readonly SemaphoreSlim _semaphore = new SemaphoreSlim(1, 1); 15 public async Task Print (int i) { 16 await _semaphore.WaitAsync(); 17 Console.WriteLine (i + " start"); 18 await Task.Delay (4000); 19 Console.WriteLine (i + " end"); 20 _semaphore.Release(); 21 } 22}

投稿2020/11/17 11:33

編集2020/11/17 11:48
BluOxy

総合スコア2663

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

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

BluOxy

2020/11/17 11:45 編集

「Main()の中身は変えない」という条件があるならば、BクラスにSemaphoreSlimなり使う方法になるのではないでしょうか。その場合、AクラスではなくBクラスが自分自身の処理の終了を待つことになります。
BluOxy

2020/11/17 11:56

後者は排他制御という手段を使っています。詳しくは調べてください。 また、補足ですがawaitを含むコードを排他制御したい場合は下記の理由から lock ステートメントは使わないようにしてください。 ・lockステートメントの開始と終了は同一のスレッドでないといけない ・awaitの呼び出し前後は違うスレッドで処理されることがある
nankoko

2020/11/17 13:33

BluOxyさん、たいへん早いお返事ありがとうございます。 求めていた完璧な回答でした。助かりました! 排他制御、勉強になりました。 ご親切に補足まで教えて頂き、lockステートメントに関しても調べてみようと思います。 ありがとうございます!
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.46%

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

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

質問する

関連した質問