当代码告诉它关闭C#.NET时,我的应用程序不会关闭 [英] My application wont close when the code tells it to close C# .NET

查看:46
本文介绍了当代码告诉它关闭C#.NET时,我的应用程序不会关闭的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

您好!我有一个打开EXE的应用程序,并在一定时间后关闭它们,问题很简单。它不会关闭它打开的应用程序,我试过Process.Kill();和TheNameOfTheVariable.Close();



但它不会关闭,如果我做Process.Kill();它给我一个错误说

无法处理请求,因为该进程已退出。





如果我这样做

TheNameOfTheVariable.Close();它只是加载并重新启动计时器。



任何解决方案?



  private   void  timer1_Tick( object  sender, EventArgs e)
{
var firstProcess = Process.Start(textBoxFirst.Text);
int timeOne = Convert.ToInt32(MinTextBoxFirst.Text);
Thread.Sleep(timeOne);
// firstProcess.Kill();
// if(!firstProcess.HasExited)firstProcess.Kill();
// firstProcess.Kill();
// MessageBox.Show(进程已被杀死!);
firstProcess.Close();



}







我' ve评论了我尝试过的其他方法。







更改







我更改了代码,删除了计时器并使用了代码

私有 void startlbl_Click ( object sender,EventArgs e)
{
Process.Start(textBoxFirst.Text);
Process.Start(textBoxFirst.Text);
Process.Start(textBoxFirst.Text);
Process.Start(textBoxFirst.Text);
Process.Start(textBoxFirst.Text);

var firstProcess = Process.Start(textBoxFirst.Text);
int timeOne = Convert.ToInt32(MinTextBoxFirst.Text);
Thread.Sleep(timeOne);
firstProcess.Kill();
}

它给了我这个错误

类型 System.dll

附加信息:无法处理请求,因为该流程已退出。







更改v2.0



 使用系统; 
使用 System.Collections.Generic;
使用 System.ComponentModel;
使用 System.Data;
使用 System.Drawing;
使用 System.Linq;
使用 System.Runtime.InteropServices;
使用 System.Text;
使用 System.Threading.Tasks;
使用 System.Windows.Forms;
使用 System.Diagnostics;
使用 System.Threading;

命名空间 Software_Restarter
{
public partial class Form1:Form
{
public Form1()
{
InitializeComponent();
}



public const int WM_NCLBUTTONDOWN = 0xA1;
public const int HT_CAPTION = 0x2;

[DllImportAttribute( user32.dll)]
public static extern int SendMessage( IntPtr hWnd, int 消息, int wParam, int lParam);
[DllImportAttribute( user32.dll)]
public static extern bool ReleaseCapture();

private void label1_Click( object sender,EventArgs e)
{
this .Close();
}

private void panel1_MouseDown( object sender,MouseEventArgs e)
{
if (e.Button == MouseButtons.Left)
{
ReleaseCapture();
SendMessage(句柄,WM_NCLBUTTONDOWN,HT_CAPTION, 0 );
}
}

私有 void BrowseFirst_Click( object sender,EventArgs e)
{
OpenFileDialog ofd = new OpenFileDialog() ;
if (ofd.ShowDialog()== System.Windows.Forms.DialogResult.OK)
{
string FilePath = ofd.FileName;
textBoxFirst.Text = FilePath;
}
}

私有 void BrowseSecond_Click( object sender,EventArgs e)
{
OpenFileDialog ofd1 = new OpenFileDialog() ;
if (ofd1.ShowDialog()== System.Windows.Forms.DialogResult.OK)
{
string FilePath = ofd1.FileName;
textBoxSecond.Text = FilePath;
}
}

私有 void BrowseThird_Click( object sender,EventArgs e)
{
OpenFileDialog ofd2 = new OpenFileDialog() ;
if (ofd2.ShowDialog()== System.Windows.Forms.DialogResult.OK)
{
string FilePath = ofd2.FileName;
textBoxThird.Text = FilePath;
}
}

私有 void startlbl_Click( object sender,EventArgs e)
{
Process.Start(textBoxFirst.Text);
Process.Start(textBoxFirst.Text);
Process.Start(textBoxFirst.Text);
Process.Start(textBoxFirst.Text);
Process.Start(textBoxFirst.Text);

var firstProcess = Process.Start(textBoxFirst.Text);
int timeOne = Convert.ToInt32(MinTextBoxFirst.Text);
Thread.Sleep(timeOne);
firstProcess.Kill();
// if(!firstProcess.HasExited)firstProcess.Kill();
// firstProcess.Kill();
// MessageBox.Show(进程已被杀死!);
/ / firstProcess.Close();
}
}
}
}







添加了我的源代码^



我尝试了什么:



我注释了我尝试过的方法。

解决方案

BladeLogan写道:



我将有其他线程,如果我要编写整个计时器进程,它会是一个更多的代码,我只是尽可能地尽力而为。你没有回答关于计时器的使用(这不是一个单独的过程,但线程可以是单独的)。

为了让你当前的进程自行终止,你必须终止你的每一个其他线程。它可以以不同的方式完成;你可以让线程自己退出,使用一些逻辑和线程间通信,或者中止它们(中止需要关心并清楚地了解你在做什么;这不是一个琐碎的事情。



(顺便提一下,一种类型的计时器, System.Windows.Forms.Timer 总是在当前UI线程中调用事件处理程序,并且在这方面最容易使用,但是如果你需要任何看起来像或多或少周期性的行为,这种类型完全不适合,因为它过于宽泛在准确性根本不重要的情况下,它可用于实现某些类型的超时。)
或者,您可以创建所有其他线程后台线程,然后运行时将终止它们,但是,在大多数情况下,我不建议它,因为那样你就不能终止这种线程可控。在某些情况下,使用后台线程是可以接受的;请参阅: Thread.IsBackground属性(System.Threading) )



我会对计时器非常小心。在有关定时器询问CodeProject的许多问题中,我很少看到使用定时器是合理的,在绝大多数情况下,使用它们是误解。这点可以给你带来最大的麻烦。



-SA


我尝试使用硬编码变量进行编码:

  var  firstProcess = Process.Start( @  D:\Documents\AA备份\ My Projects \ UtilityApplications\BulkFileRename\bin\Release\\ \\BulkFileRename.exe); 
int timeOne = 5000 ;
Thread.Sleep(timeOne);
firstProcess.Kill();



应用程序打开,等待几秒钟,然后再次关闭。我没有得到任何错误。

我怀疑它是导致它的定时器 - 检查定时器的间隔,并确保它比你睡眠线程的时间长,或者禁用定时器正在进行手术。它可能只是看起来没有关闭,因为计时器意味着你再次打开它。

我非常不愿意在计时器Tick事件处理程序中使用Thread.Sleep - 你可能会得到使用计时器决定是否需要打开应用程序,等待一段时间或关闭它而不是在其中进行睡眠,这是一个更好的结果。并且请记住,Sleep参数以毫秒为单位 - 因此,如果您输入较小的值,则在尝试终止之前应用程序可能无法完全运行。


Hello! I have a application that is opening EXE's and the closes them after a certain ammount of time and the issue is quite simple.. It wont close the applications it opens, I tried Process.Kill(); and TheNameOfTheVariable.Close();

But it wont close, if I do Process.Kill(); It gives me a error saying

Cannot process request because the process has exited.



and if i do
TheNameOfTheVariable.Close(); it just loads and restarts the timer.

Any solutions?

private void timer1_Tick(object sender, EventArgs e)
{
    var firstProcess = Process.Start(textBoxFirst.Text);
    int timeOne = Convert.ToInt32(MinTextBoxFirst.Text);
    Thread.Sleep(timeOne);
   // firstProcess.Kill();
   // if (!firstProcess.HasExited) firstProcess.Kill();
   // firstProcess.Kill();
   // MessageBox.Show("The Process Has Been Killed!");
    firstProcess.Close();



}




I've commented out other methods I've tried using.



CHANGES



I changed up the code, removed the timer and used this code

        private void startlbl_Click(object sender, EventArgs e)
        {
            Process.Start(textBoxFirst.Text);
            Process.Start(textBoxFirst.Text);
            Process.Start(textBoxFirst.Text);
            Process.Start(textBoxFirst.Text);
            Process.Start(textBoxFirst.Text);

            var firstProcess = Process.Start(textBoxFirst.Text);
            int timeOne = Convert.ToInt32(MinTextBoxFirst.Text);
            Thread.Sleep(timeOne);
            firstProcess.Kill();
        }

and it gives me this error

An unhandled exception of type 'System.InvalidOperationException' occurred in System.dll

Additional information: Cannot process request because the process has exited.




CHANGES v2.0

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Runtime.InteropServices;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using System.Diagnostics;
using System.Threading;

namespace Software_Restarter
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
        }

        

        public const int WM_NCLBUTTONDOWN = 0xA1;
        public const int HT_CAPTION = 0x2;

        [DllImportAttribute("user32.dll")]
        public static extern int SendMessage(IntPtr hWnd, int Msg, int wParam, int lParam);
        [DllImportAttribute("user32.dll")]
        public static extern bool ReleaseCapture();

        private void label1_Click(object sender, EventArgs e)
        {
            this.Close();
        }

        private void panel1_MouseDown(object sender, MouseEventArgs e)
        {
            if (e.Button == MouseButtons.Left)
            {
                ReleaseCapture();
                SendMessage(Handle, WM_NCLBUTTONDOWN, HT_CAPTION, 0);
            }
        }

        private void BrowseFirst_Click(object sender, EventArgs e)
        {
            OpenFileDialog ofd = new OpenFileDialog();
            if(ofd.ShowDialog() == System.Windows.Forms.DialogResult.OK)
            {
                string FilePath = ofd.FileName;
                textBoxFirst.Text = FilePath;
            }
        }

        private void BrowseSecond_Click(object sender, EventArgs e)
        {
            OpenFileDialog ofd1 = new OpenFileDialog();
            if (ofd1.ShowDialog() == System.Windows.Forms.DialogResult.OK)
            {
                string FilePath = ofd1.FileName;
                textBoxSecond.Text = FilePath;
            }
        }

        private void BrowseThird_Click(object sender, EventArgs e)
        {
            OpenFileDialog ofd2 = new OpenFileDialog();
            if (ofd2.ShowDialog() == System.Windows.Forms.DialogResult.OK)
            {
                string FilePath = ofd2.FileName;
                textBoxThird.Text = FilePath;
            }
        }

        private void startlbl_Click(object sender, EventArgs e)
        {
            Process.Start(textBoxFirst.Text);
            Process.Start(textBoxFirst.Text);
            Process.Start(textBoxFirst.Text);
            Process.Start(textBoxFirst.Text);
            Process.Start(textBoxFirst.Text);

            var firstProcess = Process.Start(textBoxFirst.Text);
            int timeOne = Convert.ToInt32(MinTextBoxFirst.Text);
            Thread.Sleep(timeOne);
             firstProcess.Kill();
            // if (!firstProcess.HasExited) firstProcess.Kill();
            // firstProcess.Kill();
            // MessageBox.Show("The Process Has Been Killed!");
            //firstProcess.Close();
        }
}
    }
}




Added my source code ^

What I have tried:

I commented out the methods I've tried using.

解决方案

BladeLogan wrote:


I will have other threads and if I would code the whole timer process it would be a lot more code, I'm just trying to do it as profficient as possible.

You did not answer about the timer use (this is not a separate process, but the thread can be separate).
To allow your current process to terminate itself, you have to terminate each of your other threads. It can be done in different ways; you can let threads exit by themselves, using some logic and inter-thread communications, or Abort them (aborting needs care and clear understanding of what you are doing; this is not a trivial thing).

(By the way, one type of timers, System.Windows.Forms.Timer always calls event handlers in the current UI thread and is the easiest to use, in this respect, but if you need any behavior which is supposed to look like more or less periodic, this type is totally unsuitable, due to its prohibitively low timing accuracy. It can be used for implementing some kinds of timeouts, in cases where accuracy is not critical at all.)
Alternatively, you can make all additional thread background threads, then the runtime will terminate them, but, in most cases, I don't advise it, because then you cannot make termination of such thread controllable. In certain situations, using background thread is acceptable though; please see: Thread.IsBackground Property (System.Threading).

I would be very careful with timers. In so many questions related to timers asked on CodeProject, I could see very few cases when using timers was reasonable, in absolute majority of cases, the use of them was misconception. This is the point which could give you the most of trouble.

—SA


When I try you code with "hardcoded" variables:

var firstProcess = Process.Start(@"D:\Documents\AA Backed Up\My Projects\UtilityApplications\BulkFileRename\bin\Release\BulkFileRename.exe");
int timeOne = 5000;
Thread.Sleep(timeOne);
firstProcess.Kill();


The app opens, waits a few seconds, and closes again. I get no error.
I suspect it's the Timer that's causing it - check the interval on the timer, and make sure it is longer than the amount of time you Sleep your thread for, or disable the timer while the operation is going on. It's possible that it just appears not to be closing because the timer means you keep opening it again.
I'd be very reluctant to use Thread.Sleep in a timer Tick event handler anyway - you might get a better result using the timer to decide if you need to open the app, wait a while, or close it instead of Sleeping inside it. And do remember that the Sleep parameter is in milliseconds - so if you are entering small values, the app may not be fully running before you try to kill it.


这篇关于当代码告诉它关闭C#.NET时,我的应用程序不会关闭的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆