我正在编写一个C#.net应用程序。 目前,Main表单上有一个计时器,在代码运行时从800秒开始运行。 当主表单加载时它会在1800秒时生成第二个表单和第二个计时器。当主窗体运行并完成时,它会将第二个窗体上的计时器更新回1800.如果第二个窗体的计时器达到0,则会发送一封电子邮件。
基本上我正在使用第二种形式运行看门狗定时器。
我遇到的问题是当代码在主窗体上运行时,一切都会锁定,直到完成为止。
这是第二个表格代码(看门狗)
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
namespace PGEN_v3
{
public partial class WatchDog : Form
{
public static int counter = 0;
public WatchDog()
{
InitializeComponent();
}
private void btn_TestWatch_Click(object sender, EventArgs e)
{
string strFrom = "PGEN@xxxxx";
string strTo = "xxxx@xxxx";
string strSubject = "xxxx";
string strBody = "xxxx";
Form1.sendEmail(strFrom, strTo, strSubject, strBody);
}
private void WatchDog_Load(object sender, EventArgs e)
{
this.ControlBox = false;
counter = 1800;
lbl_WATCHCOUNT.Text = counter.ToString();
timer1.Interval = 1000;
timer1.Start();
}
private void timer1_Tick(object sender, EventArgs e)
{
counter--;
lbl_WATCHCOUNT.Text = counter.ToString();
if (counter == 0)
{
string strFrom = "PGEN@xxxxx";
string strTo = "xxxx@xxxx";
string strSubject = "xxxx";
string strBody = "xxxx";
Form1.sendEmail(strFrom, strTo, strSubject, strBody);
}
}
}
}
以下是主表单代码的示例
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
namespace PGEN_v3
{
public partial class Form2 : Form
{
int counter = 0;
public Form2()
{
InitializeComponent();
}
private void Form2_Load(object sender, EventArgs e)
{
counter = 800;
lbl_MainCounter.Text = counter.ToString();
timer1.Interval = 1000;
timer1.Start();
}
private void Button_Scan_Click(object sender, EventArgs e)
{
//RUN CODE
counter = 800;
watchdogform.counter = 1800;
}
private void timer1_Tick(object sender, EventArgs e)
{
if (counter == 0)
{
Button_Scan_Click(sender, e);
}
counter--;
lbl_MainCounter.Text = counter.ToString();
}
}
}
我怎样才能得到第二种形式来产生一个不同的线程并且它不会锁定孩子? 它还会锁定主窗体上的倒计时器,直到代码完成。 我的示例代码可能不是100%工作,因为我只是从实际工作代码中提取了一些部分。它应该给你这个想法。
这是一个例子。甚至不涉及第二种形式。 当计时器达到0时,扫描开始。我希望定时器计数器继续倒计时。它会冻结,直到scan()完成。您需要两个标签,一个计时器和一个列表框。它检查路径是否对20,000个不同的路径有效。扫描大约需要7分钟才能完成。
using System;
using System.Collections;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.Data.SqlClient;
using System.IO;
using System.Net;
using System.Net.Mail;
using System.Configuration;
using System.Xml;
using System.Threading;
namespace WindowsFormsApplication1
{
public partial class Form1 : Form
{ int counter = 0;
public Form1()
{
InitializeComponent();
}
private void Form1_Load(object sender, EventArgs e)
{
counter = 6;
label2.Text = counter.ToString();
timer1.Interval = 1000;
timer1.Start();
}
private void Scan()
{
DataTable table = GetProjects();
foreach (DataRow row in table.Rows)
{
String PN = row["ProjectNumber"].ToString();
string PATH = GetPath100(PN, "R:\\");
bool PATHCHECK = !Directory.Exists(PATH);
while ( PATHCHECK)
{
label1.Text = PATH.ToString();
listBox1.Items.Add(PATH);
}
}
}
public static DataTable GetProjects()
{
DataTable dataTable = new DataTable();
SqlConnection conn = new SqlConnection("Data Source=server;Initial Catalog=db;User ID=user;Password=passwd");
string query = "Select ProjectNumber, ProjectManager, Date FROM [ProjMgt].[dbo].[tblProjectInfo] where ISNUMERIC(projectnumber) = 1 and len(ProjectNumber) >= 6 order by CAST(ProjectNumber AS int)";
SqlCommand cmd = new SqlCommand(query, conn);
conn.Open();
SqlDataAdapter dt = new SqlDataAdapter(cmd);
dt.Fill(dataTable);
return dataTable;
}
public string GetPath100(String PN, String STORAGEPATH)
{
int TENS = (Int32.Parse(PN) / 10) * 10;
int HUNDREDS = (Int32.Parse(PN) / 100) * 100;
int THOUSANDS = (Int32.Parse(PN) / 1000) * 1000;
//PATH = TENS.ToString;
String PATH = STORAGEPATH + "" + HUNDREDS + " JOBS\\" + TENS + " JOBS\\" + PN;
//Console.WriteLine("R:\\" + HUNDREDS + " JOBS\\" + TENS + " JOBS\\" + PN);
return PATH;
}
private void timer1_Tick(object sender, EventArgs e)
{
if (counter == 0)
{
Scan();
}
counter--;
label2.Text = counter.ToString();
}
}
}
由于
答案 0 :(得分:0)
好的,我在另一个论坛上找到了其他人。我需要在一个单独的线程中运行代码的一部分。
我在计时器部分添加了这个。
new Thread(() =>
{
Thread.CurrentThread.IsBackground = true;
/* run your code here */
Scan();
}).Start();
然后我不得不添加
this.Invoke((MethodInvoker)delegate
{
lbl_MainCounter.Text = counter.ToString();
WatchDog.counter = 1800;
});
在父级用户界面上需要更新的任何内容。
感谢您的帮助。