89083


提示コードの`Input.cs`の`public static async void setPlayList(string
url)`関数ですが`await`してほしくなくまた`Data.cs`のコンストラクタ部でも`await`して実行を待機してほしくありません、しかし`visual
studio`上で以下の警告が出ますこれはどうしてでしょうか？`await`は実行を待機するキーワードではないのでしょうか？

##### 警告

[code]

    warning CS4014: この呼び出しを待たないため、現在のメソッドの実行は、呼び出しが完了するまで続行します。呼び出しの結果に 'await' 演算子を適用することを検討してください。
    
    warning CS1998: この非同期メソッドには 'await' 演算子がないため、同期的に実行されます。'await' 演算子を使用して非ブロッキング API 呼び出しを待機するか、'await Task.Run(...)' を使用してバックグラウンドのスレッドに対して CPU 主体の処理を実行することを検討してください。
    
[/code]

##### 知りたいこと

１，目的の動作は実装できたのですがこれは実装として正解なのか知りたい。  
２，その場合`///`部で発生する上記の二つの警告文は無視していいのか知りたい  
３，`Debug.WriteLine()`関数を使って処理を確認しました非同期で実行されているのですがなぜ同期処理という警告なのでしょうか？

##### 参考サイト

<https://rksoftware.wordpress.com/2016/05/25/001-4/>  
<https://qiita.com/mxProject/items/e2b2271fd26cfc8b059c>

##### 環境

OS: windows10  
IDE: Visual studio 2022  
言語 C#  
作成したプロジェクト windows form GUI  
バージョン .Net 6.0

##### 試したこと

`Debug.WriteLine();`を利用して動作を確認しましたが非同期実行されているように見えます。

##### Input.cs

[code]

            /* ########################### プレイリストを設定 ###########################*/
            public static async void setPlayList(string url)　//warning CS1998
            {
                Action job = () =>
                {
                    Process process = new Process();
                    process.StartInfo.FileName = "yt-dlp";
                    process.StartInfo.RedirectStandardOutput = true;
                    process.StartInfo.RedirectStandardError = true;
                    process.StartInfo.CreateNoWindow = true;            // コンソール・ウィンドウを開かない
                    process.StartInfo.UseShellExecute = false;          // シェル機能を使用しない
                    //process.OutputDataReceived += Output_EventHandle;         //出力
                    //process.ErrorDataReceived += OutputError_EventHandle;     //エラー
                    process.StartInfo.Arguments = "--flat-playlist --ignore-errors --no-warnings --no-check-certificate --get-url " + url + " -o \"%(url)s\" ";
    
    
                    process.Start();
    
                    //process.WaitForExit();
                    //Debug.WriteLine(process.StandardOutput.ReadToEnd());
    
    
                    List<string> urlList = new List<string>();
                    StringReader sr = new StringReader(process.StandardOutput.ReadToEnd());
                    string? line = sr.ReadLine();
                    while (line != null)
                    {
                        //Debug.WriteLine("いいいいいい" + line);
                        urlList.Add(line);
    
                        line = sr.ReadLine();
                    }
    
                    //URLを設定
                    foreach (string item in urlList)
                    {
                        downloadList_Data.Add(new Data(item));
                    }
    
                    process.Close();
                };
    ////////////////////////////////////////////////////
                Task.Run(job);//warning CS4014
    ////////////////////////////////////////////////////
                Debug.WriteLine("ああああ");
            }
    
    
[/code]

##### Data.cs

[code]

            /* ########################### 初期化 ###########################*/
            public Data(string u)
            {
                SetData(u);             
            }
    
            /* ########################### データを設定 ###########################*/
            private async void SetData(string u)
            {
                url = u;
                Action job = () =>
                {
                    process.StartInfo.FileName = "yt-dlp";
                    process.StartInfo.RedirectStandardOutput = true;
                    process.StartInfo.RedirectStandardError = true;
                    process.StartInfo.CreateNoWindow = true;            //コンソール・ウィンドウを開かない
                    process.StartInfo.UseShellExecute = false;          //シェル機能を使用しない
                    process.ErrorDataReceived += this.Output_Error;
    
    
                    //タイトルを取得                
                    process.StartInfo.Arguments = " --no-warnings --get-title " + u + " -o " + "\"%(title)s\"";
                    process.OutputDataReceived += SetTitle_EventHandle;
    
                    process.Start();
    
                    process.BeginOutputReadLine();
                    process.BeginErrorReadLine();
    
                    process.WaitForExit();
    
                    process.CancelOutputRead();
                    process.CancelErrorRead();
    
                    //フォーマットを取得     
                    process.StartInfo.Arguments = " --no-warnings --get-title " + u + " -o " + "\"%(title)s\"";
                    process.OutputDataReceived -= SetTitle_EventHandle;
                    process.OutputDataReceived += SetFormat_EventHandle;
    
                    process.Start();
    
                    process.BeginOutputReadLine();
                    process.BeginErrorReadLine();
    
                    process.WaitForExit();
    
                    process.CancelOutputRead();
                    process.CancelErrorRead();
    
                    process.Close();
    
                    Debug.WriteLine("終了: " + getTitle());
    
                    
                    form.setCheckBoxList(getTitle());
                   
                };
    ////////////////////////////////////////////////////////////
                Task.Run(job);  //非同期を処理を実行
    ////////////////////////////////////////////////////////////
              
            }
    
    
    
[/code]


CC BY-SA 4.0
2022-05-26T02:23:56.997
89060
2022-05-28T03:19:29.467
2022-05-27T05:02:35.453
question
c#
C# await演算子使わないコードでこの警告文は何を意味しているのか知りたい。


`await`しないのであれば、メソッドの定義も`async`としないでください。  
`Task.Run()`による非同期処理はasync/awaitでの非同期処理の前によく使われていた方法です。

[async および await を使用した非同期プログラミング](https://docs.microsoft.com/ja-
jp/dotnet/csharp/programming-guide/concepts/async/)

また`Task.Run()`の後に待つ処理が無い場合は、Taskが終了する前にプログラムが終了する可能性がある＝Taskの完了を保証できないので、警告が出る…ということです。


CC BY-SA 4.0
2022-05-27T07:09:12.007
89083
2022-05-27T07:09:12.007
8647
89060
answer


質問 1, 2 に対してはコメント欄で書きましたが再掲します。

> １，目的の動作は実装できたのですがこれは実装として正解なのか知りたい。

「目的の動作は実装できた」のであれば、それがあなたにとっての正解ではないのですか。「実装として正解」かどうかなんて議論しても意味ないと思いますけど。私にとっての正解はあなたにとって不正解かもしれないし。

> ２，その場合///部で発生する上記の二つの警告文は無視していいのか知りたい

警告を無視してあなたの目的が果たせるのであれば無視するのが正解だと思います。

実際に動かして試す環境はあなたしか持ってないし、あなたの期待することも詳しくは他人には分からないのだから、質問 1, 2
については上記以上のことは私は言えません。

> ３，Debug.WriteLine()関数を使って処理を確認しました非同期で実行されているのですがなぜ同期処理という警告なのでしょうか？

CS1998 と CS4014 の警告が解せないということですよね。質問者さんのケースで警告は何を言っているかと言うと:

warning CS1998: async 修飾子でメソッドが非同期であると指定するとともに内部で await を使えるようにしたんだよね？ なのに
await が使われてないけどいいの？

warning CS4014: Task.Run(job) でメインスレッドとは別のスレッドで job が実行されるようにしているが、await を付与して
job が終わるまで待機しなくていいの？

・・・ということだと思います。

上の「いいの？」に対して、質問者さんは問題ないという判断なのですよね。であれば警告なので無視するか、警告を抑制するということになると思います。

質問者さんのケースでは async を削除すれば警告は消えると思います。動作にも影響はないと思います。

ただし、CS4014
については以下のドキュメントに書いてあるように「非同期呼び出しの完了を待つ必要がなく、呼び出されたメソッドで例外が発生しないことが確実である場合に限り、警告を抑制することを検討してください」とのことなので、そのあたりはよく考えた方が良さそうです。

コンパイラの警告 (レベル 1) CS4014  
<https://docs.microsoft.com/ja-jp/dotnet/csharp/language-reference/compiler-
messages/cs4014>

もう一つ、勘違いしているかもしれないので念のため書いておきます。async というのはただの修飾子です。メソッドが非同期であると指定するとともに内部で
await を使えるようにするものです。async を付与したからと言って非同期になるわけではありません。詳しくは以下のドキュメントを見てください。

async (C# リファレンス)  
<https://docs.microsoft.com/ja-jp/dotnet/csharp/language-
reference/keywords/async>

* * *

【追記】

もう一つ注意事項を思い出したので書いておきます。

上に「Task.Run(job) でメインスレッドとは別のスレッドで job
が実行される」と書きましたが、その別スレッドはバックグラウンドスレッドになります。メインスレッドはフォアグラウンドスレッドになります。

なので、メインスレッドを終了させると job はシャットダウンされます。Task.Run(job)
で別スレッドで独自に動いて完了することを期待していると不都合があるかもしれません。

フォアグラウンド スレッドとバックグラウンド スレッド  
<https://docs.microsoft.com/ja-jp/dotnet/standard/threading/foreground-and-
background-threads>


CC BY-SA 4.0
2022-05-27T07:35:06.847
89085
2022-05-28T03:19:29.467
2022-05-28T03:19:29.467
51338
51338
89060
answer