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

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

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

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

Q&A

解決済

3回答

3229閲覧

C# Task.Run()のラムダ式じゃない書き方を教えてください。

hamaa

総合スコア45

C#

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

0グッド

0クリップ

投稿2017/08/14 13:31

string[] task = await Task.Run(async () => { Task.Delay(1); // ( // ) //複数行の処理 // ( // ) string[] 返り値 = { 処理結果1,処理結果2 ,処理結果3 }; return 返り値;//結果をかえす });

これにより非同期の処理が出来ていますがコードが長すぎて辛いです。
ラムダ式部分を、名前のある引数付のdelegate。(引数付のメソッド名)に置き換えたいです
Task.Run()をwebで調べるとラムダ式のモノしか見つからず…
素人の為書き方が分からず困っています。

また、delegateの場合以下の使用法で非同期出来る様ですが

delegate void d(); IAsyncResult a = d.BeginInvoke(new AsyncCallback(cl), null); //非同期処理の終了を待ち、結果を取得 d.EndInvoke(a);

この方法はあまりよくない?古い?とか… 詳しく分からないのでその辺りも教えてください。

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

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

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

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

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

guest

回答3

0

まずTask.Run()のラムダ以外の書き方ですが、Taskクラスのヘルプを参照するとRunメソッドも色々とバリエーションがあります。
質問のコードに合わせてRun<TResult>(Func<TResult>)を使って書くとこのような感じでしょうか。

C#

1 private string[] Foo() 2 { 3 string[] result = { "a", "b", "c" }; 4 return result; 5 } 6 7 private async void Bar() 8 { 9 Func<string[]> FooFunc = Foo; 10 string[] ar = await Task.Run<string[]>(FooFunc); 11 }

async/awaitが使えるバージョンではTask.Run()の出番は少なくなり、次のようにより簡潔に記述することができます。

C#

1 private async Task<string[]> FooAsync() 2 { 3 //await Task.Delay(1); 4 string[] result = { "a", "b", "c" }; 5 return result; 6 } 7 8 private async void Bar() 9 { 10 string[] ar = await FooAsync(); 11 }

asyncキーワードの付いたメソッドは戻り値をTaskで包んでくれるため、Task.Run()の記述を無くすことができます。

投稿2017/08/15 02:55

shimitei

総合スコア799

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

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

hamaa

2017/08/15 04:07

なるほど~もうこれで非同期出来ちゃうんですね。ありがとうごさいます。 すごい勉強になります。
guest

0

ベストアンサー

名前のある引数付のdelegate。(引数付のメソッド名)に置き換えたい

の意味がわからない(そもそも引数ないラムダ式書いてるやん…?)んですが、とりあえず例示のコードを単純にdelegateに書き換えれば以下のようになります。

元コード(ちょっと手直し)

C#

1 var results1 = await Task.Run(async () => 2 { 3 await Task.Delay(1); 4 //複数行の処理 5 string[] 返り値 = { "処理結果1", "処理結果2", "処理結果3" }; 6 return 返り値; 7 });

delegateコード

C#

1 var results2 = await Task.Run(async delegate 2 { 3 await Task.Delay(1); 4 //複数行の処理 5 string[] 返り値 = { "処理結果1", "処理結果2", "処理結果3" }; 6 return 返り値; 7 });

で、たぶんやりたいのはこーゆーこと?
実ロジック切り出しコード

C#

1 //ラムダ式 2 Func<Task<string[]>> func1 = async () => 3 { 4 await Task.Delay(1); 5 //なんか色々処理 6 return new string[] { "処理結果1", "処理結果2", "処理結果3" }; 7 }; 8 var result3 = await Task.Run(func1); 9 10 //delegate 11 Func<Task<string[]>> func2 = async delegate 12 { 13 await Task.Delay(1); 14 //なんか色々処理 15 return new string[] { "処理結果1", "処理結果2", "処理結果3" }; 16 }; 17 var result4 = await Task.Run(func2);

ラムダ式の中のロジックを別に切り出したい、と読み取りました。いかがでしょう。

そもそもコードが長いのは適切なクラス設計・メソッド分割がなされていないだけで、例示したコードのようにfuncを定義して切り出すような書き方はあんまり見かけません。

やりたいことが非同期コードなのか、ラムダ式を除去したいのか、delegateを使ってみたいだけなのか、単にコードのリファクタリングの一環なのか、質問からはちょっと特定できません…。

投稿2017/08/15 02:07

ShikaTech

総合スコア468

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

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

hamaa

2017/08/15 02:18

ShikaTech さん >>ラムダ式の中のロジックを別に切り出したい、と読み取りました。 ありがとうございます。その通りです。 >>そもそもコードが長いのは適切なクラス設計・メソッド分割がなされていないだけで、例示したコードのようにfuncを定義して切り出すような書き方はあんまり見かけません。 はい。おっしゃる通りです。まだまだ素人でクラス設計・メソッド分割が経験浅いです。とりあえず動かす所から始めてます。 >>質問からはちょっと特定できません…。 日本語が下手ですみません。でも、読み取って頂き助かりました。 コードをみて勉強させていただきます。
ShikaTech

2017/08/15 02:26 編集

意図通りの例示ができたようで何よりです。 楽しく学んでいきましょう!C#はサイコーですぞ! 補足ですが、引数がほしければ例示のコードを以下のように書き換えてみてくださいな。 →Func<string,Task<string[]>> func1 = async (string arg) => これで、Inにstring型、OutにTask<string[]>型のFunctionが定義できます。 さらに呼び出し側を引数対応にして実行! →var result3 = await Task.Run(() => func1("param"));
hamaa

2017/08/15 02:28

ありがとうございます。C#に度ハマり中です。 ご親切にありがとうございます。
guest

0

結局ラムダ式を使ってるやん!
っていう回答ですがやりたいことは実現できてると思うのでこれでどうでしょうか
(ラムダ式の中で関数を呼ぶイメージです)

csharp

1class Program 2{ 3 static void Main(string[] args) 4 { 5 Console.WriteLine("タスク開始"); 6 7 //パラメータ 8 var param = true; 9 10 //呼び出し 11 var task = Task.Run(() => HeavyTask(param)); 12 13 Console.WriteLine("タスク待機"); 14 15 //待機 16 task.Wait(); 17 Console.WriteLine($"Result = {task.Result}"); 18 Console.WriteLine("終了"); 19 Console.ReadKey(); 20 } 21 22 static bool HeavyTask(bool param) 23 { 24 //なんか重たい処理 25 System.Threading.Thread.Sleep(2000); 26 return param; 27 } 28}

投稿2017/08/15 01:57

MMashiro

総合スコア2378

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

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

hamaa

2017/08/15 02:20

azio_groupさん ありがとうございます。目的は長いコードの切だしです。 どちらの方々もありがとうございます。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.48%

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

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

質問する

関連した質問