

Visual C#にて、現在あるWindows formアプリを作っています。  
チェックボックスにチェックを入れると、その間はずっと裏で別の作業をしていて欲しいです。  
その際UIはかたまらないようにしたいと思い、非同期処理で作ることにしました。  
下記が自分が現在考えているコーディングなのですが、async/awaitを使った無限ループの非同期処理はこんな感じであっていますかね。  
つたない文章で申し訳ありませんが、どなたかご指摘お願いします。

[code]

    private async void 仕事1_CheckedChange(object sender, EventArgs e)
    {
        if ( 仕事1.Checked )                                  // Aさん：もしチェックされたら
        {
            try                                               // Aさん：Bさんこれやってみて
            {
                await Task.Run( async( ) => 仕事1( ) ) ;      // Aさん：Bさんに仕事1やってもらう。それまで他の仕事しとくね、問題起きたら報告頂戴
            }
            catch ( Exception ex )                            // Aさん：問題起きてるかチェックするよ
            {
                仕事1.Checked = false ;                       // Aさん：問題が起きたからチェック外しとくね
                AddLog( ex + "\r\n" , Color.Blue ) ;          // Aさん：起きた問題はログブックに書き込んどくよ
            }
        }
    }
    
    private async Task 仕事1( )
    {
        while ( 仕事1.Checked )                               // Bさん：もしチェックされてたら、されてる間はずっと
        {
            書き込み作業( pid , addr , ofst ) ;               // Bさん：書き込み作業します
            await Task.Delay( 150 ).ConfigureAwait( false ) ; // Bさん：0.15秒次の作業遅れます。遅れてもAさんには支障ないです
        }
        書き込み作業終了( pid , addr , ofst ) ;               // Bさん：チェックが解除されたから書き込み作業終了します
    }
    
[/code]

早くにご回答感謝します...。  
別スレッドからUI側の条件を持ってきたい、となるとこうすればよろしいのでしょうか。

[code]

    var tokenSource = new CancellationTokenSource( ) ;                 // Aさん：仕事1をやめる時の条件を作っておくよ
    var token = tokenSource.Token ;                                    // Aさん：その条件はこれね
    
    private async void 仕事1_CheckedChange(object sender, EventArgs e)
    {
        if ( 仕事1.Checked )                                           // Aさん：もしチェックされたら
        {
            try                                                        // Aさん：Bさんこれやってみて
            {
                await Task.Run( async( ) => 仕事1( token ) , token ) ; // Aさん：Bさんに仕事1やってもらう。それまで他の仕事しとくね、問題起きたら報告頂戴
            }
            catch ( Exception ex )                                     // Aさん：問題起きてるかチェックするよ
            {
                仕事1.Checked = false ;                                // Aさん：問題が起きたからチェック外しとくね
                AddLog( ex + "\r\n" , Color.Blue ) ;                   // Aさん：起きた問題はログブックに書き込んどくよ
            }
        }
        else                                                           // Aさん：もしチェックが外れたら
        {
            tokenSource.Cancel( ) ;                                    // Aさん：仕事1はやめてもらうよ
        }
    }
    
    private async Task 仕事1( CancellationToken token )
    {
        while ( true )                                                 // Bさん：Aさんから仕事中止の命令がこない間はずっと
        {
            書き込み作業( pid , addr , ofst ) ;                        // Bさん：書き込み作業します
            await Task.Delay( 150 ).ConfigureAwait( false ) ;          // Bさん：0.15秒次の作業遅れます。遅れてもAさんには支障ないです
            if ( token.IsCancellationRequested )                       // Bさん：Aさんから仕事中止の命令がきたら
            {
                書き込み作業終了( pid , addr , ofst ) ;                // Bさん：チェックが解除されたから書き込み作業終了します
                break ;                                                // Bさん：書き込み作業はやめます
            }
        }
    }
    
[/code]


CC BY-SA 4.0
2018-08-30T06:28:52.177
47935
2018-08-30T07:56:05.020
2018-08-30T07:56:05.020
29922
29922
question
c# 非同期 マルチスレッド
async/awaitによる非同期処理の無限ループの書き方について


>
[code]

>     await Task.Run( async( ) => 仕事1( ) ) ;
>  
[/code]

は`仕事1()`を別スレッドで実行することを意味します。なお、WinFormsでは別スレッドからGUI要素（コントロール）を操作することは許されていません。そのため、`仕事1()`メソッド内の

>
[code]

>     while ( 仕事1.Checked )
>  
[/code]

は不正なアクセスです。


CC BY-SA 4.0
2018-08-30T06:53:42.877
47936
2018-08-30T06:53:42.877
4236
47935
answer


@sayuriさん指摘原因により問題があるので、チェックにはCancellationTokenを使用しましょう。この辺の記事を参照してみてください。

[非同期で複数処理を実行し、対話式で制御する](https://qiita.com/haminiku/items/cc299c1ed94d7ba3f9ec)  
[方法: タスクとその子を取り消す](https://docs.microsoft.com/ja-jp/dotnet/standard/parallel-
programming/how-to-cancel-a-task-and-its-children)  
[.NET
FrameworkのCancellationTokenを利用してタスクをキャンセルすると振る舞いが2種類ある問題](http://mag.autumn.org/Content.modf?id=20161124183521)


CC BY-SA 4.0
2018-08-30T06:59:09.537
47937
2018-08-30T07:07:41.550
2018-08-30T07:07:41.550
26370
26370
47935
answer