直列つなぎ。 -とある発達障害者の記録

知識と知識を繋ぐためのblog。 広汎性発達と診断されました。ぜんぜん役に立ってないけど。月収13万円、家賃4万円で生活するひつじ人間。

注釈 C#:第17回 処理を委譲するdelegate

第17回 処理を委譲するdelegate
http://www.atmarkit.co.jp/fdotnet/csharp_abc/csharp_abc_017/csharp_abc01.html





http://ufcpp.net/study/csharp/sp_delegate.html
通常ならメソッドは単に処理を返すだけだが、デリゲートは同時に処理結果を変数に代入したり、入力した値に条件を指定したり、複数の処理を変数に代入したりできる。それに伴って非同期処理を行わせることも出来る。


 処理順は「移譲先メソッド(AsynchronousMethod)→ 移譲元メソッド(Main():)」。
thread.sleepを挟むと処理順は変わる()。

using System;
using System.Threading;

namespace A
{
  /// <summary>
  /// メッセージを表示するだけのデリゲート
  /// </summary>
  public delegate void ShowMessage(int n);

  public class Program
  {
    static void Main()
    {
      const int N = 6;
      ShowMessage asyncCall = new ShowMessage(AsynchronousMethod);

      // asyncCall を非同期に(呼び出しと同時に戻る)呼び出す。
      IAsyncResult ar = asyncCall.BeginInvoke(N, null, null);

      // ↓この部分は asyncCall によって呼び出されるメソッドと同時に実行されます。
      for(int i=0; i<N; ++i)
      {
        Thread.Sleep(600);
       //待ってる間にMainの処理が行われる。非同期。
       //スリープなしだとデリゲート先の処理が優先される。
        Console.Write("Main ({0})\n", i);


 } // asyncCall の処理が終わるのを待つ。 asyncCall.EndInvoke(ar); Console.Write(" 処理完了\n"); } static void AsynchronousMethod(int n) { for(int i=0; i<n; ++i) { Thread.Sleep(1000); Console.Write("AsynchronousMethod ({0})\n", i); } } static void B(IAsyncResult ar){}
         } }

スリープの時間によって処理の順番が変わる。
スリープなしだと
AsynchronousMethodが先に呼び出される。
処理の重さで処理順の割り振りを決めたりするのか。

//スリープなしの結果
AsynchronousMethod (0)
AsynchronousMethod (1)
AsynchronousMethod (2)
AsynchronousMethod (3)
AsynchronousMethod (4)
AsynchronousMethod (5)
Main (0)
Main (1)
Main (2)
Main (3)
Main (4)
Main (5)
処理完了


// Thread.Sleep(2000);
Main (0)
Main (1)
Main (2)
AsynchronousMethod (0)
Main (3)
Main (4)
Main (5)
AsynchronousMethod (1)
AsynchronousMethod (2)
AsynchronousMethod (3)
AsynchronousMethod (4)
AsynchronousMethod (5)
処理完了



// Thread.Sleep(500);
AsynchronousMethod (0)
Main (0)
AsynchronousMethod (1)
Main (1)
AsynchronousMethod (2)
Main (2)
AsynchronousMethod (3)
Main (3)
AsynchronousMethod (4)
Main (4)
AsynchronousMethod (5)
Main (5)
 処理完了


述語
 
インターフェースとよく似た機能・構造に思える
 
条件はstaticメソッドで指定した値を返している。

述語 isOver10 (指定した条件内の値を返す) → デリゲート先処理(Select):述語をパラメータとしている。→   デリゲート元(Main)


 static void Main()
    {
        int[] x = new int[] { 1, 8, 4, 11, 8, 15, 12, 19 };

        // x の中から値が 10 以上のもだけ取り出す
        Console.Write("10以上"+"\n");
      
        int[] y = Select(x, new Predicate(IsOver10));
        foreach (int i in y)
            Console.Write("{0},", i);
        Console.Write("\n");


        Console.Write("5-15の範囲 \n");
        // x の中から値が (5, 15) の範囲にあるものだけ取り出す
        int[] z = Select(x, new Predicate(Is5to15));
        foreach (int i in z)
        Console.Write("{0},  ",i);
        Console.Write("\n");
    }


  static bool IsOver10(int n){return n > 10;}
  static bool Is5to15(int n){return (n > 5) && (n < 15);}

 
  static int[] Select(int[] x, Predicate pred)
    {
        int n = 0;
        foreach (int i in x)
    //x[]回列挙する。これなら要素の数は問題にならない。
            if (pred(i)) ++n;

        int[] y = new int[n];

        n = 0;
        foreach (int i in x)
            if (pred(i))
            {
                y[n] = i;
                ++n;
            }

        return y;
    }


関連記事
スポンサーサイト

 C#

0 Comments

Leave a comment