1

我有一个 winforms 应用程序,我将通过任务调度程序调用它来下载文件并将它们插入数据库。但是,文件何时可用是不可预测的,因此我使用 timer ( 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()是必要的,因为没有它,计时器只会滴答一次,然后应用程序将退出。

那么如何正确地告诉应用程序退出呢?或者我应该在哪里打电话Application.Run()

4

4 回答 4

0

这听起来有点奇怪——也许你应该简单地将 Application.exit 移动到一个单独的过程中,如果你需要退出程序,只需更改一些布尔变量。在您的主程序中,您可以等待布尔值更改然后退出程序一次。此外,您可以在开始时将布尔变量设置为 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()

所以为了解决这个问题,我只是在计时器的刻度方法中添加了一个条件,以确保它们在第一次运行时不会发生任何事情。

我不同意将程序重组为它所代表的方式我可以通过任务调度程序运行它以每天下载文件而无需表单和轮询功能,我也可以通过 VS 将其作为带有按钮的普通 winforms 应用程序运行用于在出现问题时进行测试、调试和下载文件。

于 2012-11-05T06:17:18.253 回答
-1

为了保持你的主方法运行(保持它的线程活跃),你可以使用 Thread.Sleep 而不是 Application.Run()。尝试这个:

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

而不是 Application.Exit() 使用:

Process.GetCurrentProcess().Kill();

这种方式可以工作,但请考虑为此使用 Windows 服务。

于 2012-11-02T13:48:30.363 回答