2016-05-10 7 views
0

C#の非同期フローを示すために、簡単なプログラム (Pythonとの相違点を示すために、GILのためにPythonが同期しているため)を作成しました。C#プログラムの非同期フロー

なぜ関数func2()関数func1を待っているの実行がある()を終了するには?関数func1()で

void main() 
{ 
    Console.WriteLine("main"); 
    func1(); 
    func2(); 
} 
public void func1() 
{ 
    Console.WriteLine("func1"); 
    double i = 0; 
    while(true) 
    { 
     i += 1; 
     if (i > 100000000) 
     { 
     break; 
     } 
    } 
    func(3); 
    func(4); 
} 
public void func2() 
{ 
    Console.WriteLine("func2"); 
    func(5); 
    func(6); 
} 
public void func(int number) 
{ 
    Console.WriteLine(number); 
} 

は、私がメイン()関数func2を続けると呼んように、プログラムウェイトを作るためにループを実行しています()FUNC前(3)及びFUNC(4)。しかし、すべての時間は、それがこの順で同期ファッションやプリント出力で動作します:

main 
func1 
3 
4 
func2 
5 
6 

すなわち関数func2()は、常に私は、非同期の流れに期待していなかったFUNC4()後に呼び出されます。

なぜ関数func2()関数func1を待っているの実行がある()を終了するには?

おかげ

+0

「async」キーワードについて読んでください。あなたはそれ以外の場合は、彼らはPythonは可能性が順番 – Ghost

+3

に行われる必要があると仮定します、それは非同期で物事を行うには大丈夫だプログラムを指示する必要があり、非同期すぎ... –

+0

サイドノート:考えるが、「スクリプト」の独自の定義を考え出すていませんか、 "プログラミング" - これはあなたのポストの周りで不要な議論を引き起こす可能性があります。それは本当にあなたの質問に関連していません。 –

答えて

4

C#があなたのプログラムは、同期がありません。すべてのプログラムは同期しています(マルチコアを除く)。 OSも同期して実行され、さまざまなプログラムに実行スライスを与えることによって並列処理の錯覚を与えます。プログラムを並列に実行させたい場合は、明示的に指示する必要があります。 C#/ .NETにはこれを行うための多くのメカニズムがありますが、言語が非同期であると言うのは公正ではありません。マルチスレッドコードはC言語で書かれ、ウィンドウ上で実行されますが、並列処理をサポートしていない組み込みシステムで作業している場合は、実行できません。

1

あなたは関数func2が終了するfunc1のために待機しない場合、あなたはそれを伝える必要があります:

class Program 
{ 
    static void Main(string[] args) 
    { 
     Console.WriteLine("main"); 
     doWork(); 
    } 
    public async static void doWork() 
    { 
     Task<int> longTask = func1(); //Start func1 
     func2(); //Call func2 while we wait 
     int output = await longTask; //Wait for func2 to be finished 
    } 
    public async static Task<int> func1() 
    { 
     Console.WriteLine("func1"); 

     await Task.Delay(10000); //delay, could make func(3) and func(4) run in the meantime if we wanted.... 

     func(3); 
     func(4); 
     return 0; 
    } 
    public static void func2() 
    { 
     Console.WriteLine("func2"); 
     func(5); 
     func(6); 
    } 
    public static void func(int number) 
    { 
     Console.WriteLine(number); 
    } 
} 

出力:

main 
func1 
func2 
5 
6 
3 
4 
+0

ハローゴースト、お返事に感謝。 C#は非同期ではありません(asyncキーワードを使用しない)?コールバック()を使用して、ある関数が別の関数の後に実行されることを確認する理由の1つ。 – user2259784

+0

他にも使用できる構造体がありますが、 'async'は最新のものです。それらのコンストラクトの1つを使用していない場合は、各命令を個別に順番に実行します。 – Ghost

1

をするたびにメソッドが呼び出されるので、これが発生し、中C#では、パラメータに渡された情報はスタック(呼び出しスタック)に格納されます。このスタックは、最後に最初に実装されます。 は、だからあなたの例ではfunc1が呼び出されたときに、それがスタックに移行して、mainメソッドが停止し、スタックを残すためにfunc1のを待ちます。 https://en.wikipedia.org/wiki/Call_stack

非同期フローがなければ何もできませんし、Pythonでも同じと思われます。

は、しかし、あなたは簡単に非同期に実行するようにコードを変更することができます。

public static void Main() 
{ 
    Console.WriteLine("main"); 
    var t = func1(); 
    func2(); 
    t.Wait(); 
} 

public static Task func1() 
{ 
    Console.WriteLine("func1"); 
    return Task.Factory.StartNew(() => { 
     double i = 0; 
     while(true) 
     { 
      i += 1; 
      if (i > 100000000) 
      { 
      break; 
      } 
     } 
     func(3); 
     func(4); 
    }); 
} 
public static void func2() 
{ 
    Console.WriteLine("func2"); 
    func(5); 
    func(6); 
} 
public static void func(int number) 
{ 
    Console.WriteLine(number); 
}