C# 为什么我的程序在计时器代码运行时会冻结?
我的程序是在ROBLOX打开时自动打开另一个程序。我知道这很奇怪,但对我很有帮助。一旦程序打开,我的按钮和一切都可以正常工作。一旦我启用它并打开ROBLOX,应用程序就会中断,直到ROBLOX关闭。只是冻结,没有错误。也不会打开其他应用程序。请帮忙C# 为什么我的程序在计时器代码运行时会冻结?,c#,C#,我的程序是在ROBLOX打开时自动打开另一个程序。我知道这很奇怪,但对我很有帮助。一旦程序打开,我的按钮和一切都可以正常工作。一旦我启用它并打开ROBLOX,应用程序就会中断,直到ROBLOX关闭。只是冻结,没有错误。也不会打开其他应用程序。请帮忙 using System.Collections.Generic; using System.ComponentModel; using System.Data; using System.Diagnostics; using System.Draw
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Diagnostics;
using System.Drawing;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
namespace ProtoSmasher_Auto_Opener
{
public partial class Form1 : Form
{
string path;
public Form1()
{
InitializeComponent();
}
private void Form1_Load(object sender, EventArgs e)
{
if(!File.Exists(@"c:\PSAutoStart\path.proto"))
{
MessageBox.Show("It seems like this is your first time running. Please make sure File Manager is closed for your first run.", "Notice");
}
if (File.Exists(@"c:\PSAutoStart\path.proto"))
{
string lastPath;
using (StreamReader sr = new StreamReader(@"c:\PSAutoStart\path.proto"))
{
lastPath = sr.ReadToEnd();
}
textBox1.Text = lastPath;
path = lastPath;
}
}
private void button1_Click(object sender, EventArgs e)
{
if (button1.BackColor != System.Drawing.Color.Red)
{
if(textBox1.Text == "")
{
MessageBox.Show("Please click browse and locate ProtoSmasher to activate.", "Error");
}
else
{
button1.BackColor = System.Drawing.Color.Red;
button1.Text = "Deactivate";
timer1.Start();
}
}
else
{
button1.BackColor = System.Drawing.Color.Green;
button1.Text = "Activate";
timer1.Stop();
}
}
private void button3_Click(object sender, EventArgs e)
{
OpenFileDialog fileDialog = new OpenFileDialog();
fileDialog.Filter = "ProtoSmasher (*.exe)|*.exe";
if (fileDialog.ShowDialog() == System.Windows.Forms.DialogResult.OK)
{
path = fileDialog.FileName;
if (!File.Exists(@"c:\PSAutoStart\path.proto"))
{
DirectoryInfo di = Directory.CreateDirectory(@"c:\PSAutoStart");
try
{
System.Threading.Thread.Sleep(2 * 1000);
StreamWriter sw = File.CreateText(@"c:\PSAutoStart\path.proto");
sw.WriteLine(path);
textBox1.Text = path;
}
catch (Exception ex)
{
MessageBox.Show("Didn't I tell you to close your file manager first?", "Error");
}
}
else
{
using (StreamWriter sw = File.CreateText(@"c:\PSAutoStart\path.proto"))
{
sw.WriteLine(path);
}
textBox1.Text = path;
}
}
}
private void timer1_Tick(object sender, EventArgs e)
{
Process[] roblox = Process.GetProcessesByName("RobloxPlayerBeta");
if (roblox.Length > 0)
{
try
{
Process.Start(textBox1.Text);
stillRunning.Start(); //to keep from spamming open
timer1.Stop();
}
catch(Exception ex)
{
MessageBox.Show("Something went wrong: " + ex, "Error");
}
}
}
private void stillRunning_Tick(object sender, EventArgs e)
{
Process[] roblox = Process.GetProcessesByName("RobloxPlayerBeta");
if(roblox.Length > 0)
{ }
else
{
timer1.Start();
stillRunning.Stop();
}
}
}
}
在.NET中有十几个计时器。我想知道这是Windows窗体计时器: 每个线程只能运行一段代码。WindowsForms计时器在GUI线程中运行。计时器在这方面有很多变化,但是您可能还必须处理交叉线程安全问题。我想你应该在组合中加入一些明确的多任务处理 多任务处理是一个非常棘手的问题,需要学习。我通常的学习建议是在WindowsForms应用程序中使用BackgroundWorker。您可能不想在生产代码中看到它,但它是一个非常好的“训练轮”。我还有一些关于如何使用它的老例子:
#region Primenumbers
private void btnPrimStart_Click(object sender, EventArgs e)
{
if (!bgwPrim.IsBusy)
{
//Prepare ProgressBar and Textbox
int temp = (int)nudPrim.Value;
pgbPrim.Maximum = temp;
tbPrim.Text = "";
//Start processing
bgwPrim.RunWorkerAsync(temp);
}
}
private void btnPrimCancel_Click(object sender, EventArgs e)
{
if (bgwPrim.IsBusy)
{
bgwPrim.CancelAsync();
}
}
private void bgwPrim_DoWork(object sender, DoWorkEventArgs e)
{
int highestToCheck = (int)e.Argument;
//Get a reference to the BackgroundWorker running this code
//for Progress Updates and Cancelation checking
BackgroundWorker thisWorker = (BackgroundWorker)sender;
//Create the list that stores the results and is returned by DoWork
List<int> Primes = new List<int>();
//Check all uneven numbers between 1 and whatever the user choose as upper limit
for(int PrimeCandidate=1; PrimeCandidate < highestToCheck; PrimeCandidate+=2)
{
//Report progress
thisWorker.ReportProgress(PrimeCandidate);
bool isNoPrime = false;
//Check if the Cancelation was requested during the last loop
if (thisWorker.CancellationPending)
{
//Tell the Backgroundworker you are canceling and exit the for-loop
e.Cancel = true;
break;
}
//Determin if this is a Prime Number
for (int j = 3; j < PrimeCandidate && !isNoPrime; j += 2)
{
if (PrimeCandidate % j == 0)
isNoPrime = true;
}
if (!isNoPrime)
Primes.Add(PrimeCandidate);
}
//Tell the progress bar you are finished
thisWorker.ReportProgress(highestToCheck);
//Save Return Value
e.Result = Primes.ToArray();
}
private void bgwPrim_ProgressChanged(object sender, ProgressChangedEventArgs e)
{
pgbPrim.Value = e.ProgressPercentage;
}
private void bgwPrim_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
{
pgbPrim.Value = pgbPrim.Maximum;
this.Refresh();
if (!e.Cancelled && e.Error == null)
{
//Show the Result
int[] Primes = (int[])e.Result;
StringBuilder sbOutput = new StringBuilder();
foreach (int Prim in Primes)
{
sbOutput.Append(Prim.ToString() + Environment.NewLine);
}
tbPrim.Text = sbOutput.ToString();
}
else
{
tbPrim.Text = "Operation canceled by user or Exception";
}
}
#endregion
#区域素数
私有无效btnPrimStart\单击(对象发送者,事件参数e)
{
如果(!bgwPrim.IsBusy)
{
//准备进度条和文本框
int temp=(int)nudPrim.Value;
pgbPrim.最大值=温度;
tbPrim.Text=“”;
//开始处理
bgwPrim.RunWorkerAsync(临时);
}
}
私有无效btnprimmcancel\u单击(对象发送者,事件参数e)
{
如果(bgwPrim.IsBusy)
{
bgwPrim.CancelAsync();
}
}
私有void bgwPrim_DoWork(对象发送方,DoWorkEventArgs e)
{
int highestToCheck=(int)e.参数;
//获取运行此代码的BackgroundWorker的引用
//用于进度更新和取消检查
BackgroundWorker thisWorker=(BackgroundWorker)发件人;
//创建存储结果并由DoWork返回的列表
列表素数=新列表();
//检查1和用户选择的任何上限之间的所有不均匀数
对于(int PrimeCandidate=1;PrimeCandidate
然而,我有点不确定你的程序甚至做什么。使用特定字符串获取所有进程并强制关闭它们?在.NET中,只有十几个计时器。那是哪一个?这是WindowsForms计时器:它在主线程中运行。你需要在这里使用某种形式的多任务处理。对于初学者,我建议在WindowsForm中使用BackgroundWorker。我熟悉c#,但并不擅长。是否有关于后台工作人员及其工作方式的文档?这可能也值得一读:不,这不是强制关闭任何文件。基本上,当ROBLOX打开时,程序应该会检测到它。一旦检测到,它将打开另一个应用程序并停止计时器,这样它就不会打开该应用程序。第二个计时器确保ROBLOX仍在运行,当它没有运行时,再次启动计时器以检测ROBLOX。@Zeridiant听起来像是一个不需要UI的执事,因此可以通过轮询锁定其主线程。当然,如果请求取消,它需要一种中断轮询的方法。甚至可能是Windows服务在任何程序中添加执事功能都是可能的,但是你总是需要一个额外的线程来完成这项工作。@Zeridiant然而,通常对某些事情做出反应的最佳方式是首先启动它。如果您需要桌面链接,DRM/更新程序系统(如Steam或Epic)将使用一个技巧作为启动程序,并且仍然有一个桌面图标:Web链接。您可以设置要注册到某些协议的程序,包括自定义的“steam:”和“com.epicgames.launcher:”。添加一些单实例机制,将请求中继到正在运行的实例中,这样就可以了。