C# winApp ต้องการให้โค้ดทำงาน ถึงแม้จะปิดหน้าฟอร์มนั้นๆ ไป ครับ
เนื่องจากว่า ผมรันหน้านี้มา 3 ชั่วโมงกว่าๆ ทำอย่างอื่นในโปรแกรมไม่ได้เลย
จึงมานั่งคิดว่า มีวิธีไหนที่จะช่วยได้บ้าง
คือต้องการ user สามารถทำงานอื่นต่อได้ โดยอาจจะทำงานเบื้องหลัง ก็ได้ครับ
แต่มันนาน ผมก็กลัวว่า user จะเผลอปิดหน้านี้ไป ครับ
โค้ดครับ
Code (C#)
private class F_717_Lot
{
public int ID;
public int Digit;
public double Down3SD;
public double Up3SD;
public F_717_Lot(int id, int dg, double d, double u)
{
ID = id;
Digit = dg;
Down3SD = d;
Up3SD = u;
}
}
List<string> sqls;
void SaveData(DateTime dateTime1, DateTime dateTime2, List<F_717_Lot> _LotIDs)
{
DateTime dt01 = dateTime1, dt02 = dateTime2, dt_value;
double[] v = new double[10];
List<F_717_Lot> LotIDs = _LotIDs;
dt_value = dllExtension.ExtenedDatetime.RandomTodayTime(dt01, 8, 10);
Action<F_717_Lot,int ,int> getSQL = (l,start,final) =>
{
dt_value = dllExtension.ExtenedDatetime.RandomTodayTime(dt_value, start, final);
lblAddDataStatus.Invoke(new Action(() => lblAddDataStatus.Text = "Adding date.." + dt_value));
for (int a = 0; a < 10; a++)
v[a] = ExtenedDataGridView.rnd.NextDouble(l.Down3SD, l.Up3SD, l.Digit);
string name = ExtForm.RandomName(Names);
sqls.Add( "INSERT [dbo].[ALS_F_717] VALUES('" + l.ID + "','" +
dt_value + "','" +r.NextDouble(24.5, 28.5, 2) + "','" + r.Next(48, 60) + "','" +
v[0] + "','" + v[1] + "','" + v[2] + "','" + v[3] + "','" + v[4] + "','" + v[5] + "','" +
v[6] + "','" + v[7] + "','" + v[8] + "','" + v[9] + "','" + v.Average() + "','" + true +
"','" + name + "','' )");
};
while (dt_value < dt02)
{
System.Threading.Thread.Sleep(200);
if (dt_value.DayOfWeek != DayOfWeek.Sunday)
{
LotIDs.ForEach(lotid =>
{
getSQL(lotid,8,10);
getSQL(lotid, 13, 15);
});
}
dt_value = dt_value.AddDays(1);
};
}
string FolTemp;
List<string> Names;
private void cmdSave6021_Click(object sender, EventArgs e)
{
FolTemp = Path.GetTempPath() + $@"DATA_LAB";
sqls = new List<string>();
List<F_717_Lot> LotIDs = new List<F_717_Lot>();
for (int i = 0; i < aLS_F_717_Lot_AVGDataGridView.RowCount - 1; i++)
{
if (aLS_F_717_Lot_AVGDataGridView[1, i].Value != null)
{
if (Convert.ToBoolean(aLS_F_717_Lot_AVGDataGridView[0, i].Value))
{
LotIDs.Add(new F_717_Lot((int)aLS_F_717_Lot_AVGDataGridView[1, i].Value,
Convert.ToInt32(aLS_F_717_Lot_AVGDataGridView[3, i].Value.ToString().Trim()),
Convert.ToDouble(aLS_F_717_Lot_AVGDataGridView[4, i].Value.ToString().Trim()) - 2.9 * Convert.ToDouble(aLS_F_717_Lot_AVGDataGridView[5, i].Value.ToString().Trim()),
Convert.ToDouble(aLS_F_717_Lot_AVGDataGridView[4, i].Value.ToString().Trim()) + 2.9 * Convert.ToDouble(aLS_F_717_Lot_AVGDataGridView[5, i].Value.ToString().Trim())));
}
}
}
string combinedFilePath = "";// = FolTemp + $@"\AutoSave ALS717 {DateTime.Now.ToString("yyyyMMdd hhmmss ffff")}.sql";
using (SaveFileDialog SaveFileDialog1 = new SaveFileDialog())
{
SaveFileDialog1.InitialDirectory = Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments);
SaveFileDialog1.Title = "Save sql Files";
SaveFileDialog1.DefaultExt = "sql";
SaveFileDialog1.Filter = "sql files (*.sql)|*.sql";
SaveFileDialog1.FileName = $@"Save ALSF717 {DateTime.Now.ToString("yyyyMMdd hhmmss ffff")}.sql";
if (SaveFileDialog1.ShowDialog() == DialogResult.OK)
{
combinedFilePath = SaveFileDialog1.FileName;
}
}
using (WaitFormDialog f = new WaitFormDialog(new Action(() =>
{
using (frmEmpSelect ff = new frmEmpSelect())
{
ff.ShowDialog();
if (ff.Names.Count > 0)
{
Names = ff.Names;
DateTime dt01 = dtpStart.Value;
DateTime dt02;
List<Task> tasks = new List<Task>();
while (dt01 < dtpFinal.Value)
{
System.Threading.Thread.Sleep(200);
DateTime date = dt01.AddDays(15);
dt02 = date >= dtpFinal.Value ? dtpFinal.Value : date;
tasks.Add(Task.Factory.StartNew(() => SaveData(dt01.ToDatetimeThai(), dt02.ToDatetimeThai(), LotIDs)));
System.Threading.Thread.Sleep(5000);
dt01 = dt02;
}
// Wait for the tasks to complete before displaying a completion message.
Task.WaitAll(tasks.ToArray());
System.Threading.Thread.Sleep(1000);
// string[] sqlFiles = Directory.GetFiles(FolTemp, "*.sql");
StringBuilder combinedSql = new StringBuilder();
int countSave = 0;
combinedSql.Append("USE [DATALAB] \r\nGO\r\n");
foreach (string sql in sqls)
{
combinedSql.AppendLine(sql);
countSave++;
if (countSave >= 300)
{
combinedSql.AppendLine("\nGO\n");
countSave = 0;
}
}
Directory.CreateDirectory(Path.GetDirectoryName(combinedFilePath));
using (StreamWriter writer = File.CreateText(combinedFilePath))
{
writer.Write(combinedSql.ToString());
}
}
}
// File.WriteAllText(combinedFilePath, combinedSql.ToString());
MessageBox.Show("Compete");
})))
{
f.ShowDialog(this);
grpAutoSaveData.Visible = false;
this.aLS_F_717TableAdapter.FillByLotID(aLS_F_717DataSet.ALS_F_717, LotID);
//dgv.Sort(dgv.Columns[2], ListSortDirection.Ascending);
aLS_F_717DataGridView.Sort(aLS_F_717DataGridView.Columns[2], ListSortDirection.Ascending);
if (aLS_F_717DataGridView.Rows != null && aLS_F_717DataGridView.Rows.Count > 0)
{
int lastRowIndex = aLS_F_717DataGridView.Rows.Count - 1;
aLS_F_717DataGridView.CurrentCell = aLS_F_717DataGridView.Rows[lastRowIndex].Cells[2];
}
}
}
การทำงานคือ สุ่มค่าต่างๆ วันละ 2 รอบ ยกเว้น (วันอาทิตย์) มาลงในไฟล์ sql จากนั้นจะรันไฟล์ sql เพื่อบันทึกข้อมูล ครับ
ประเด็นปัญหาจะมี 2 ข้อคือ
1. ทำยังไง ให้วสามารถ รันโค้ดให้เร็วขึ้นได้
2. ถ้าทำให้เร็วไม่ได้ ทำยังไงให้ไม่สะดุด หากเผลอปิดหน้านี้ไป เปิดมาใหม่ มันต้องอัพเดทข้อมูลที่รันอยู่เบื้องหลัง
ตอนนี้ที่ทำได้คือ
Code (C#)
List<Task> tasks = new List<Task>();
และ
Code (C#)
tasks.Add(Task.Factory.StartNew(() => SaveData(dt01.ToDatetimeThai(), dt02.ToDatetimeThai(), LotIDs)));
โดยแบ่งทำงาน task ละ 10 วัน ถ้ารัน 1 ปี ก็ 36 task พร้อมๆ กัน
ซึ่ง SaveData จะรันวันละ 2 รอบ เช้า บ่าย
Code (C#)
LotIDs.ForEach(lotid =>
{
getSQL(lotid,8,10);
getSQL(lotid, 13, 15);
});
และ
getSQL จะสุ่มค่า ต่างๆ มาเก็บ ใน
Code (C#)
sqls.Add( "INSERT [dbo].[ALS_F_717] VALUES('" + l.ID + "','" +
dt_value + "','" +r.NextDouble(24.5, 28.5, 2) + "','" + r.Next(48, 60) + "','" +
v[0] + "','" + v[1] + "','" + v[2] + "','" + v[3] + "','" + v[4] + "','" + v[5] + "','" +
v[6] + "','" + v[7] + "','" + v[8] + "','" + v[9] + "','" + v.Average() + "','" + true +
"','" + name + "','' )");
เสร็จงานทุกอย่างจาก
Code (C#)
Task.WaitAll(tasks.ToArray());
ก็จะบันทึกใน
Code (C#)
$@"Save ALSF717 {DateTime.Now.ToString("yyyyMMdd hhmmss ffff")}.sql";
Code (C#)
StringBuilder combinedSql = new StringBuilder();
int countSave = 0;
combinedSql.Append("USE [DATALAB] \r\nGO\r\n");
foreach (string sql in sqls)
{
combinedSql.AppendLine(sql);
countSave++;
if (countSave >= 300)
{
combinedSql.AppendLine("\nGO\n");
countSave = 0;
}
}
Directory.CreateDirectory(Path.GetDirectoryName(combinedFilePath));
using (StreamWriter writer = File.CreateText(combinedFilePath))
{
writer.Write(combinedSql.ToString());
}
Tag : .NET, Win (Windows App), C#
Date :
2023-06-10 00:43:20
By :
lamaka.tor
View :
404
Reply :
6
เลือกตามที่ถนัด
1. FormClosing event
2. BackgroundWorker
3. Service
Date :
2023-06-10 09:47:36
By :
009
ตอบความคิดเห็นที่ : 3 เขียนโดย : 009 เมื่อวันที่ 2023-06-10 15:24:59
รายละเอียดของการตอบ ::
ขอบคุณมากครับ
แต่ตอนนี้ ดันมาเจอ ทางตัน
พบว่า ในแล็บมีหลายเครื่องที่ใช้รูปแบบวันที่เป็น ไทย(2566) และ หลายเครื่องใช้รูปแบบสากล(2023)
ในฐานข้อมูลจะมีทั้ง แบบไทย และ อังกฤษ มั่วไปหมดครับ
ตอนนี้เลยมาทดลองโค้ดใหม่
จากโค้ด
Code (C#)
_rooms.ForEach(_room =>
{
dt = dt.Date + ExtenedDatetime.RandomTime(8, 15);
sql += Environment.NewLine + @" ('" + dt + "'," + _room + "," + _Section + ",'" + true + "','" + true + "','" + true + "','" + true + "','','" + name + "','" + dt + "'),";
});
พบว่าในเครื่องรูปแบบ ไทย พบข้อผิดพลาด
System.Data.SqlClient.SqlException: 'The conversion of a varchar data type to a datetime data type resulted in an out-of-range value.
The statement has been terminated.'
ที่
Code (C#)
TORServices.DB.extDatabase.CreateCommandSql(sql, Properties.Settings.Default.DATALABConnectionString);
แต่ถ้าเครื่องรูปแบบอังกฤษบันทึกได้ปกติ
Code (C#)
_rooms.ForEach(_room =>
{
dt = dt.Date + ExtenedDatetime.RandomTime(8, 15);
string formattedDateTime = dt.ToString("yyyy-MM-dd HH:mm:ss"); // รูปแบบวันที่ในฐานข้อมูล SQL Server
sql += Environment.NewLine + @" ('" + formattedDateTime + "'," + _room + "," + _Section + ",'" + true + "','" + true + "','" + true + "','" + true + "','','" + name + "','" + formattedDateTime + "'),";
});
รูปแบบสากลใช้ได้ปกติ รูปแบบไทย เละไม่เอาอ่าว
ตอนนี้ ทำไปทำมา เละ เทอะ ไปหมดแล้ว ครับ 555
ถ้าไม่รอดจริง อาจจะต้องใช้วิธีตั้งค่า ทุกเครื่องเป็นแบบสากล ครับ
Date :
2023-06-10 22:20:11
By :
lamaka.tor
ลองพวก Culture ดูครับ ถ้าไม่เวิร์ก ก็ดึง server/external time เอา
Date :
2023-06-11 10:26:25
By :
009
Load balance : Server 02