5

私は本当に単純な非同期コードを書こうとしています。Windows サービスから呼び出されるパラメーターを取らない void メソッドがあります。メソッドが完了するのを待ってサービスがぶらぶらする必要がないように、非同期で開始したいと思います。

コーディングが正しく行われていることを確認するために非常に単純なテスト アプリを作成しましたが、非同期メソッドが呼び出されていません。私が間違ったことを誰でも見ることができますか?ところで、私は .NET 4.0 を使用しているため、await を使用できません (これははるかに簡単です!)。

これが私のテストサンプル全体です...

using System;
using System.Threading;

namespace AsyncCallback {
  internal class Program {
    private static void Main(string[] args) {
      Console.WriteLine(DateTime.Now.ToLocalTime().ToLongTimeString() + " - About to ask for stuff to be done");
      new Action(DoStuff).BeginInvoke(ar => StuffDone(), null);
      Console.WriteLine(DateTime.Now.ToLocalTime().ToLongTimeString() + " - Asked for stuff to be done");
    }

    private static void StuffDone() {
      Console.WriteLine(DateTime.Now.ToLocalTime().ToLongTimeString() + " - Stuff done");
    }

    private static void DoStuff() {
      Console.WriteLine(DateTime.Now.ToLocalTime().ToLongTimeString() + " - Starting to do stuff");
      Thread.Sleep(1000);
      Console.WriteLine(DateTime.Now.ToLocalTime().ToLongTimeString() + " - Ending doing stuff");
    }
  }
}

ご協力いただきありがとうございます。

4

4 に答える 4

6

非同期メソッドがにデプロイされる前に、プログラムが終了していThreadPoolます。プログラムを少し開いたままにします。おそらくConsole.ReadKey()最後にMain

于 2012-12-10T19:21:19.883 に答える
5

実行を完了していないフォアグラウンドスレッドがなくなると、アプリケーションはすべて終了します。バックグラウンドスレッドがある場合、それらはプロセスを「存続」させません。

バックグラウンドで非同期タスクを開始していて、フォアグラウンドスレッドの実行を維持しているものがないため、プロセス全体が終了しています。

代わりに、フォアグラウンドスレッドで非同期タスクを実行する必要があります(これはBeginInvoke、私が知る限りでは実行できませんThread。明示的に新しいものを作成する必要があります)。または、終了するまでメインスレッドをブロックするために何か他のことを行います。

于 2012-12-10T19:22:38.723 に答える
1

まず、コールバックは正しいデリゲートではありません...

public delegate void AsyncCallback(IAsyncResult ar);

そしてあなたのものは

private static void StuffDone()

次のように変更するだけです。

private static void StuffDone(IAsyncResult ar){}

そして、コールバックで、呼び出しによってアクションが実際に実行されることを確認します

EndInvoke

上でAsyncState

このような:

private static void StuffDone(IAsyncResult ar)
{
    Action r = ar.AsyncState as Action;
    r.EndInvoke(ar);

    Console.WriteLine(DateTime.Now.ToLocalTime().ToLongTimeString() + " - Stuff done");
}

もう 1 つ変更する必要があるのは、メイン関数でアクションをインスタンス化するときに、アクション自体をBeginInvokeメソッドの「オブジェクト」引数として次のように渡すことです。

Action d = new Action(DoStuff);
d.BeginInvoke(StuffDone, d);

これはあなたの問題を解決するはずです:)

于 2012-12-10T19:35:45.723 に答える
1

あなたは完了を待っていないので、このようなことを試してください

 Console.WriteLine(DateTime.Now.ToLocalTime().ToLongTimeString() + " - About to ask for stuff  to be done");
 var a = new Action(DoStuff);
 var iar = a.BeginInvoke(ar => StuffDone(), null);
 a.EndInvoke(iar);
 Console.WriteLine(DateTime.Now.ToLocalTime().ToLongTimeString() + " - Asked for stuff to be done");
于 2012-12-10T19:26:13.847 に答える