ฉันมีตรรกะทางธุรกิจเพื่อตรวจสอบเว็บเซอร์วิสว่าบริการนั้นยังมีอยู่หรือไม่
ฉันต้องการตรวจสอบซ้ำทุกๆ 5 นาทีเป็นเวลา 1 ชั่วโมงหลังจากเวลาเริ่มต้น
วิธีดำเนินการนี้ผ่านงานหรือเธรดหรือฟังก์ชันการรอ/อะซิงก์
ฉันมีตรรกะทางธุรกิจเพื่อตรวจสอบเว็บเซอร์วิสว่าบริการนั้นยังมีอยู่หรือไม่
ฉันต้องการตรวจสอบซ้ำทุกๆ 5 นาทีเป็นเวลา 1 ชั่วโมงหลังจากเวลาเริ่มต้น
วิธีดำเนินการนี้ผ่านงานหรือเธรดหรือฟังก์ชันการรอ/อะซิงก์
ขั้นแรก ตรวจสอบข้อกำหนดทางธุรกิจของคุณอีกครั้ง สิ่งนี้ทำให้คุณได้อะไรกันแน่? บริการเว็บอาจหายไปทันทีเมื่อใดก็ได้ ดังนั้นการที่คุณเพิ่งตรวจสอบไม่ได้หมายความว่าการโทรครั้งถัดไปของคุณจะสำเร็จ นี่เป็นเรื่องจริงสำหรับการสื่อสารเครือข่ายทั้งหมด
ดังนั้นความซับซ้อนของโค้ด "ของจริง" ของคุณจึงไม่ลดลงหากคุณมี "ตัวตรวจสอบ" แยกต่างหาก ประโยชน์เพียงอย่างเดียวของการออกแบบประเภทนี้คือการแจ้งเตือนด้วยภาพแก่ผู้ใช้ว่าพวกเขาสามารถมั่นใจได้อย่างสมเหตุสมผลว่าการโทรใช้บริการครั้งถัดไปจะสำเร็จ ถึงอย่างนั้น คุณอาจต้องการพิจารณาใหม่ เพราะมันสมเหตุสมผลเท่านั้น และผู้ใช้จะโกรธถ้าคุณโกหกพวกเขา
ที่กล่าวว่าคุณสามารถทำได้โดยใช้ Task
s ดังนี้:
private static async Task CheckAsync(CancellationToken token)
{
// Check your web service.
await CheckWebServiceAsync(token);
// Wait 5 minutes.
await Task.Delay(TimeSpan.FromMinutes(5), token);
}
...
var done = new CancellationTokenSource(TimeSpan.FromHours(1));
Task checkingTask = CheckAsync(done.Token);
// When checkingTask completes:
// IsCanceled -> One hour passed with no errors.
// IsFaulted -> The web service failed.
โซลูชันเธรดมีลักษณะดังนี้:
public class WebserviceChecker {
private int durationInHours = 1;
public void setDuration(int value) { durationInHours = value; }
private boolean _shutdown = false;
private DateTime _startTime = null;
// System.Windows.Forms.Timer
private Timer _timer = null;
public void CheckWebservice() {
_startTime = DateTime.Now;
_timer = new Timer();
_timer.Tick += handleTimerTick;
while(!_shutdown) {
try {
// do what ever you want to do for checking your webservice...
// ...
} catch (ThreadAbortedException ex) {
// do cleanup, then
//
break;
} catch (Exception ex) {
Logger.Instance.log(LoggerLogType.Type.Err, ex.ToString());
}
// wait 5 secs (customize to your needs)
Threading.Thread.Sleep(5000);
}
if(_shutdown) {
// do some regular cleanup here...
}
} // public void CheckWebservice()
public void Shutdown() {
_shutdown = true;
}
private void handleTimerTick(Object sender, System.EventArgs e) {
TimeSpan ts = _startTime .Subtract(DateTime.Now);
if(ts.TotalHours >= durationInHours) {
Shutdown();
}
}
}
และตอนนี้เริ่มเธรดพื้นหลังดังนี้:
WebserviceChecker _c = new WebserviceChecker();
Thread _watcher = new Thread(_c.CheckWebservice);
_watcher.IsBackground = true;
_watcher.Start();
สำหรับงานตามกำหนดการ ดูที่นี่: C# เริ่มงานที่กำหนดเวลาไว้
ฉันต้องการโซลูชันเธรดมากกว่าเนื่องจากการรับข้อมูลจากกระบวนการภายนอกนั้นซับซ้อนกว่าเล็กน้อย การซิงโครไนซ์ข้อมูลเธรดเข้ากับเธรดหลักของคุณนั้นง่ายกว่า คุณจะต้องมีกระบวนทัศน์เช่น IPC (Inter Process Communication) บน WCF โดยไปป์ที่มีชื่อหรือการสื่อสารซ็อกเก็ต ( TCP/UDP)
หากคุณต้องการคำแนะนำวิธีรับข้อมูลกลับจากเธรดของคุณ: คุณสามารถทำได้เช่น กำหนดเหตุการณ์ในคลาส WebserviceChecker ซึ่งคุณจะเพิ่มขึ้นเมื่อมีการเปลี่ยนแปลงสถานะของ WS ของคุณ
บางคำเกี่ยวกับสิ่งที่ IsBackground... หากคุณไม่ได้ตั้งค่าเธรดเป็นพื้นหลัง แอปพลิเคชันของคุณจะออกก็ต่อเมื่อทุกเธรดเบื้องหน้าออกจากวิธีการทำงานของเขาแล้ว เธรดพื้นหลังจะถูกยกเลิกโดยอัตโนมัติเมื่อแอปพลิเคชันปิดตัวลง
คำพูดของ ThreadAbortedException: ใน .NET เราได้รับสิทธิ์ในการยกเลิกเธรดอย่างหนัก กรอบงานจะเพิ่มข้อยกเว้นนี้ที่ตำแหน่งใดๆ ในวิธีการเธรดเพื่อออก หากคุณไม่จับมัน เธรดจะออกโดยไม่มีการล้างข้อมูล ดังนั้นเพียงแค่จับมันไว้และทำความสะอาดหน่วยความจำหรือทำงานบางอย่างให้เสร็จสิ้น คุณจะทำสิ่งนี้ที่นี่เช่นนั้น:
_watcher.Abort();
เชียร์เซธ :)
[แก้ไข] มีบทช่วยสอนการทำมัลติเธรดที่ดีที่ MSDN: http://msdn.microsoft.com/en-us/library/aa645740%28v=vs.71%29.aspx [/แก้ไข]
[แก้ไข] หากคุณต้องการใช้ System.Threading.Timer คุณต้องใช้การมอบหมาย System.Threading.TimerCallback ในคลาส Watcher ของคุณ จากนั้นคุณสามารถยกตัวอย่างตัวจับเวลาใหม่ด้วยจุดแทนเธรดพื้นหลัง ดู http://msdn.microsoft.com/de-de/library/system.threading.timercallback.aspx สำหรับรายละเอียดเพิ่มเติม [/แก้ไข]