1

タスクスケジューラを介してファイルをダウンロードしてデータベースに挿入するために呼び出すwinformsアプリケーションがあります。ただし、ファイルがいつ利用可能になるかは予測できないため、タイマー(System.Windws.Forms.Timer)を使用してファイルをポーリングしました。

 static class Program
    {
        /// <summary>
        /// The main entry point for the application.
        /// </summary>
        [STAThread]
        static void Main(string[] args)
        {
            if (args != null && args.Length > 0)
            {

                Form1 f1 = new Form1();
                if (f1.IsLive)
                {
                    f1.OnLaunch(); // tests DB connection and reads and updates the expiry date list.

                    if (args[0] == "FullStats")
                        f1.FullStatsDataPump();
                    else if (args[0] == "OptionsStats")
                    {
                        f1.OptionsStatsTimer_Tick(null, null);
                        f1.OptionsStatsTimer.Start();
                    }
                    else if (args[0] == "OptionsTraded")
                    {
                        f1._optionsTradedTimer_Tick(null, null);
                        f1.OptionsTradedTimer.Start();
                    }
                    else
                    {
                        EmailManager.InvalidInputArgument(args[0]);
                        Application.Exit();
                    }

                    Application.Run();
                }

            }

上記のコードスニペットでは、OptionsTradedTimer/OptionsStatsTimer両方がファイルをポーリングしてから、で終わるプロセスを開始しますApplication.Exit()。これは完全に実行されますが、その後、無限のメッセージループでスタックします。Application.Run()最初のタイマーが作動した直後に呼び出されるので、Application.Exit()最終的に呼び出されるとメッセージループが終了すると思いました。しかし、コードをステップスルーすると、その後Application.Exit()、プログラムは元のtimer.tick()に戻りApplication.Run()、下部のに進みます。Application.Run()下部にあるが必要なのは、それがないとタイマーが1回だけ刻み、その後アプリが終了するためです。

では、どうすればアプリケーションに終了するように正しく指示できますか?または、どこに電話すればよいApplication.Run()ですか?

4

4 に答える 4

0

これは少し奇妙に聞こえます。おそらく、Application.exitを別のプロシージャに移動し、プログラムを終了する必要がある場合はブール変数を変更するだけです。メインプログラムでは、ブール値が変化するのを待ってから、プログラムを1回終了することができます。さらに、最初にブール変数をfalseに設定して、実行する必要がないようにすることもできます。

于 2012-11-02T13:25:09.133 に答える
0

Application.Exit()を使用する必要はないと思います。Main()メソッドは、アプリケーションへのエントリポイントです。戻ると、アプリケーションは終了します。一般的に、Application.Run()は、閉じるまで実行されるWindowsフォームを起動するために使用されます。このコードを試してみてください-私はそれをテストしていませんが、あなたが望むことをするはずです。

using System.Linq;
using System.Threading;

class MyApplication
{
    [STAThread]
    static void Main(string[] args)
    {
        const string ARG_SHOWFORM = "ShowForm";
        const string ARG_STATS = "OptionsStats";
        const string ARG_TRADED = "OptionsTraded";

        if (args.Contains(ARG_SHOWFORM) || args.Length == 0) {
            Application.Run(new Form1());  //This will block until the form is closed.

            //Make sure all your supporting logic is placed into the Form.Loaded event on the form (i.e.
            //get it out of the Main() method).

            return;
        }

        if (args.Contains(ARG_STATS))
            OptionsStatsMethod();

        else if (args.Contains(ARG_TRADED))
            OptionsTradedMethod();

        else
            EmailManager.InvalidInputArgument(args[0]);

    }

    private void OptionsTradedMethod()
    {
        while (true) {
            if (downloadSuccessful) //Use a method here that returns a boolean if the download succeeded.
                break;
            else
                Thread.Sleep(DEFAULT_WAIT_TIME_MS);
        }
    }

    private void OptionsStatsMethod()
    {
        while (true) {
            if (downloadSuccessful)  //Use a method here that returns a boolean if the download succeeded.
                break;
            else
                Thread.Sleep(DEFAULT_WAIT_TIME_MS);
        }
    }
}
于 2012-11-02T13:26:33.967 に答える
0

質問を削除できないので、答えた方がいいかもしれません。

この問題は、タイマーがApplication.Exit()最初に実行されたときにラインに到達した場合にのみ発生します。(つまり、プログラムの実行時にファイルがすでに使用可能である場合)。この場合、タイマーが最初の実行でに到達しない(つまり、ファイルがまだ利用できない)かのようにApplication.Exit()前に呼び出され、その後呼び出され、後でのみ呼び出されます。Application.Run()Application.Exit()Application.Run()Application.Exit()

したがって、これを解決するために、タイマーのティックメソッドに条件を追加して、最初の実行で何も起こらないようにしました。

プログラムを現状のまま再構築することに同意しません。タスクスケジューラを介して実行し、フォームなしでポーリング機能を使用してファイルを毎日ダウンロードできます。また、ボタンを備えた通常のwinformsアプリとしてVSを介して実行することもできます。何か問題が発生したときにファイルをテスト、デバッグ、ダウンロードするため。

于 2012-11-05T06:17:18.253 に答える
-1

メインメソッドを実行し続ける(スレッドを存続させる)には、Application.Run()の代わりにThread.Sleepを使用できます。これを試して:

Thread.Sleep(System.Threading.Timeout.Infinite);

Application.Exit()の代わりに以下を使用します。

Process.GetCurrentProcess().Kill();

このように機能しますが、これにはWindowsサービスの使用を検討してください。

于 2012-11-02T13:48:30.363 に答える