简体   繁体   English

C#程序的初始形式在运行时不可用

[英]Initial Form of C# program unavailable while the program is running

I am having a problem getting the main Form in my program to run as I want. 我在使程序中的主窗体能够按需运行时遇到问题。 I am using C#. 我正在使用C#。 On my initial main form (Form1) I have a command button that runs a long program. 在最初的主窗体(Form1)上,我有一个运行长程序的命令按钮。 In the middle of the program I want the user to be able go back to the initial form and click on some new checkboxes that I will place on that initial form from within the C# program. 在程序的中间,我希望用户能够返回到初始表单并单击一些新的复选框,我将在C#程序中放置在该初始表单上。 The code below just freezes the initial form. 下面的代码只是冻结了初始表单。 I do not need to get the code below to work exactly. 我不需要获取下面的代码即可正常工作。 I just need it to allow me to access the main initial form in the middle of the program that I started with the command button. 我只是需要它来允许我访问我在命令按钮开始的程序中间的主要初始表单。

To do this I have an infinite while loop that calls the timer. 为此,我有一个无限的while循环来调用计时器。 Is this the correct way to do this? 这是正确的方法吗? I do not need the program below to work. 我不需要下面的程序来工作。 I just need to be able to access that initial Form in the middle of the program. 我只需要能够在程序中间访问该初始表格。 Since it is not working it seems that it is not the way to do this but what is the correct way? 由于它不起作用,似乎不是这样做的方法,但是正确的方法是什么?

The following code runs the OnTimedEvent function (method) below. 以下代码运行下面的OnTimedEvent函数(方法)。 The function used to put up a Messagebox but I commented that out. 该函数曾经用来放置消息框,但我对此进行了注释。 I do NOT need that function to work. 我不需要该功能即可工作。 It is only there for testing purposes. 它仅用于测试目的。 My goal is that I need the initial main Form to allow me to enter more information while it is running from the command button. 我的目标是我需要初始主表单,以便在命令按钮运行时输入更多信息。 The function below runs about 15 times and I get the error 下面的函数运行约15次,我得到了错误

Exception of type 'System.OutOfMemoryException' was thrown. 引发了类型为'System.OutOfMemoryException'的异常。

on the line aTimer.Elapsed += new ElapsedEventHandler(OnTimedEvent) ; 在线aTimer.Elapsed += new ElapsedEventHandler(OnTimedEvent) ;

The code is below: 代码如下:

System.Timers.Timer aTimer;
// Create a timer with a one second interval.
aTimer = new System.Timers.Timer(100);

while (true)
{
    // Hook up the event handler for the Elapsed event.
    aTimer.Elapsed += new ElapsedEventHandler(OnTimedEvent);

    // Only raise the event the first time Interval elapses.
    aTimer.AutoReset = false;
    aTimer.Enabled = true;  // uncommented this now
    //addded  below
    aTimer.Start();
}

I have tried it in several different ways but the main Form always just freezes. 我已经尝试了几种不同的方法,但是主窗体始终只是冻结。 I just want to be able to select things (checkboxes, for instance) on the main Form ( Form1 ) so the below code may not be needed. 我只希望能够在主窗体( Form1 )上选择内容(例如复选框),因此可能不需要以下代码。 The timer above calls OnTimedEvent which is below. 上面的计时器调用下面的OnTimedEvent

private static void OnTimedEvent(object source, ElapsedEventArgs e)
{
  // MessageBox.Show("Hello World");
}

In many places on the web I have seen (including stackoverflow) that I should be using timers to get the main initial Form to be useable but the code above just causes the Form to be Frozen and I get the bar at the top of the form indicating that it is Not Responding. 在网络上的许多地方,我已经看到(包括stackoverflow)我应该使用计时器来使主要的初始Form可用,但是上面的代码只是导致Form被冻结,并且在表单的顶部出现了横条。表示它没有响应。 I am using Windows XP and Visual Studio 2008. As I indicated above I am using C#. 我正在使用Windows XP和Visual Studio2008。如上所述,我正在使用C#。

To summarize, is the above code the correct way to get the main, Initial form to be available after a command button has been running? 总而言之,上面的代码是在命令按钮运行后获取main,Initial表单的正确方法吗? If it is, what am I doing wrong? 如果是的话,我做错了什么? If this is not the correct way, what is? 如果这不是正确的方法,那是什么?

BTW, I asked a completely unrelated question about this project here 顺便说一句,我在这里问了一个与此项目完全无关的问题

Any ideas? 有任何想法吗?

You should simply remove the while loop 你应该简单地删除while循环

    System.Timers.Timer aTimer;
    // Create a timer with a one second interval.
    aTimer = new System.Timers.Timer(1000);
    // Hook up the event handler for the Elapsed event.
    aTimer.Elapsed += new ElapsedEventHandler(OnTimedEvent);

    // Only raise the event the first time Interval elapses.
    aTimer.AutoReset = false;
    aTimer.Enabled = true;  // uncommented this now
    //addded  below
    aTimer.Start();

Timer runs on a separate Thread when you start it. 启动时,计时器在单独的线程上运行。 Your while loop just keeps starting the timer over and over again. 您的while循环只会不断重复启动计时器。

System.Timers.Timer System.Timers.Timer

To do this I have an infinite while loop that calls the timer. 为此,我有一个无限的while循环来调用计时器。 Is this the correct way to do this? 这是正确的方法吗?

No. The while loop blocks the UI thread, which in turn makes the program freeze. 否。while循环会阻塞UI线程,从而使程序冻结。 There's no reason to have the while loop as you're already using a timer to trigger the event. 由于您已经使用计时器来触发事件,因此没有理由使用while循环。

Without seeing your full, actual, code it's hard to say, but the tradtional method of doing a long-running process without locking the UI is to use Threading in C#. 在没有看到完整的,实际的代码的情况下,很难说,但是在不锁定UI的情况下执行长时间运行的流程的传统方法是在C#中使用线程。

Can you do your long running action in its own thread so that you don't lock up the UI thread? 您可以在自己的线程中执行长时间运行的操作,以便不锁定UI线程吗?

Here's a tutorial: http://msdn.microsoft.com/en-us/library/aa645740(v=vs.71).aspx 这是一个教程: http//msdn.microsoft.com/en-us/library/aa645740(v = vs.71).aspx

Don't use a while loop. 不要使用while循环。 If you want to run your OnTimedEvent method once a second, use something more like this: 如果要OnTimedEvent运行一次OnTimedEvent方法,请使用类似以下的方法:

Timer myTimer = new Timer();
myTimer.Elapsed += new ElapsedEventHandler(OnTimedEvent);
myTimer.Interval = 1000; // 1000 ms is one second
myTimer.Enabled = true;
myTimer.Start();

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM