Cara terbaik untuk menjalankan tugas yang dijadwalkan [ditutup]

229

Hari ini kami telah membangun aplikasi konsol untuk menjalankan tugas yang dijadwalkan untuk situs web ASP.NET kami. Tapi saya pikir pendekatan ini agak rawan kesalahan dan sulit dipertahankan. Bagaimana Anda menjalankan tugas yang dijadwalkan (di lingkungan windows / IIS / ASP.NET)

Memperbarui:

Contoh tugas:

  • Mengirim email dari antrian email di basis data
  • Menghapus objek yang sudah usang dari database
  • Mengambil statistik dari Google AdWords dan mengisi tabel di database.
Niels Bosma
sumber
Apa contoh tugas yang Anda jalankan?
JeffO
4
Anda perlu memeriksa atrigger.com
Kousha
Jika Anda memiliki Plesk, Anda dapat menulis vbs dan memasangnya ke Penjadwal Tugas: net24.co.nz/kb/article/AA-00213/13/Shared-Hosting/ASP-ASP.NET/…
HasanG

Jawaban:

74

Semua tugas saya (yang perlu dijadwalkan) untuk situs web disimpan dalam situs web dan dipanggil dari halaman khusus. Saya kemudian menulis layanan Windows sederhana yang sering memanggil halaman ini. Setelah halaman berjalan itu mengembalikan nilai. Jika saya tahu ada lebih banyak pekerjaan yang harus dilakukan, saya menjalankan halaman lagi, segera, kalau tidak saya menjalankannya sebentar lagi. Ini telah bekerja dengan sangat baik untuk saya dan menjaga semua logika tugas saya dengan kode web. Sebelum menulis layanan Windows yang sederhana, saya menggunakan penjadwal Windows untuk memanggil halaman setiap x menit.

Cara mudah lain untuk menjalankan ini adalah dengan menggunakan layanan pemantauan seperti Pingdom . Arahkan cek http mereka ke halaman yang menjalankan kode layanan Anda. Minta halaman mengembalikan hasil yang kemudian dapat digunakan untuk memicu Pingdom untuk mengirim pesan peringatan ketika ada sesuatu yang tidak beres.

Brettski
sumber
3
Ini adalah solusi yang akhirnya saya dapatkan. Alih-alih layanan web kustom saya menggunakan windows scheduler + curl. Apa manfaat menggunakan layanan windows.
Niels Bosma
16
Sudahkah Anda melihat teknik kedaluwarsa Cache Item? Saya pikir Anda akan menemukan bahwa ini adalah implementasi yang jauh lebih ideal dari layanan terjadwal: codeproject.com/KB/aspnet/ASPNETService.aspx
Richard Clayton
10
Apa yang harus menghentikan pengguna jahat (atau spider mesin pencari) memanggil halaman ini, dan dengan demikian menyebabkan tugas terjadwal Anda berjalan?
UpTheCreek
8
Anda dapat menghentikan panggilan jahat dengan menyimpan stempel waktu statis di aplikasi web dan hanya berjalan jika stempel waktu belum diatur (panggilan pertama) atau waktu yang benar telah kedaluwarsa sejak panggilan terakhir.
Rob Kent
5
Saya menghentikan panggilan berbahaya ke url saya dengan memeriksa apakah alamat ip adalah alamat internal atau tidak. Ia tidak mengembalikan apa-apa dan tidak melakukan apa-apa jika itu bukan internal organisasi kami.
user1408767
128

Teknik ini oleh Jeff Atwood untuk Stackoverflow adalah metode paling sederhana yang pernah saya temui. Itu bergantung pada mekanisme panggilan balik "cache item dihapus" membangun ke dalam sistem cache ASP.NET

Pembaruan: Stackoverflow telah melampaui metode ini. Ini hanya berfungsi saat situs web berjalan tetapi ini adalah teknik yang sangat sederhana yang berguna bagi banyak orang.

Lihat juga Quartz.NET

SM.
sumber
12
Jadi apa yang terjadi jika aplikasi tidak berjalan, tetapi tugas yang dijadwalkan perlu terjadi?
MichaelGG
2
Ini juga bisa memperlambat pengalaman pengguna jika tugas tersebut membutuhkan waktu untuk menjalankan waktu ini. Saya memilih untuk tidak meminta pengguna menelurkan perawatan / tugas saya untuk saya.
Brettski
5
Ini menakutkan sekali! Apa pun dapat menyebabkan aplikasi berhenti berjalan dan mungkin hanya restart pada permintaan pengguna berikutnya. Di antara saat-saat itu, tugas Anda tidak berjalan!
teedyay
43
Sesuatu yang saya perhatikan hari ini di komentar ke posting blog asli: No, we’ve switched to a dedicated task. We definitely outgrew this technique. I do think it’s fine for small sites though!- Jeff Atwood
Joel Coehoorn
3
-1 Ada kelemahan besar dengan pendekatan ini. Setiap kali aplikasi didaur ulang, acara 'CacheItemRemoved' akan menyala dan tugas terjadwal Anda akan berjalan. Di lokasi produksi, ini bisa terjadi beberapa kali sehari. Tidak begitu baik jika Anda ingin tugas dijalankan setiap minggu.
Steven de Salas
30

Buat Layanan Windows khusus .

Saya memiliki beberapa tugas penting yang diatur sebagai aplikasi konsol terjadwal dan sulit untuk dipelihara. Saya membuat Layanan Windows dengan 'detak jantung' yang akan memeriksa jadwal di DB saya setiap beberapa menit. Itu bekerja dengan sangat baik.

Karena itu, saya masih menggunakan aplikasi konsol terjadwal untuk sebagian besar tugas pemeliharaan tidak kritis saya. Jika tidak rusak, jangan memperbaikinya.

Chris Van Opstal
sumber
7
FYI tautannya sudah mati.
Charles Burns
1
@CharlesBurns, Anda selalu dapat menelusuri tautan mati dengan archive.org: web.archive.org/web/20090919131944/http
Nikolay Kostov
17

Saya menemukan ini mudah bagi semua yang terlibat:

  • Buat metode layanan web seperti DoSuchAndSuchProcess
  • Buat aplikasi konsol yang memanggil metode web ini.
  • Jadwalkan aplikasi konsol di penjadwal tugas.

Dengan menggunakan metodologi ini, semua logika bisnis terdapat di aplikasi web Anda, tetapi Anda memiliki keandalan manajer tugas windows, atau manajer tugas komersial lainnya untuk memulai dan mencatat informasi pengembalian seperti laporan eksekusi. Menggunakan layanan web alih-alih memposting ke halaman memiliki sedikit keuntungan karena lebih mudah untuk mendapatkan data pengembalian dari layanan web.

Daniel Auger
sumber
10

Mengapa menemukan kembali roda, gunakan kelas Threading dan Timer.

    protected void Application_Start()
    {
        Thread thread = new Thread(new ThreadStart(ThreadFunc));
        thread.IsBackground = true;
        thread.Name = "ThreadFunc";
        thread.Start();
    }

    protected void ThreadFunc()
    {
        System.Timers.Timer t = new System.Timers.Timer();
        t.Elapsed += new System.Timers.ElapsedEventHandler(TimerWorker);
        t.Interval = 10000;
        t.Enabled = true;
        t.AutoReset = true;
        t.Start();
    }

    protected void TimerWorker(object sender, System.Timers.ElapsedEventArgs e)
    {
        //work args
    }
Moises Goncalves
sumber
7
Anda tidak perlu menelurkan utas untuk memulai timer ...
Zyo
4
Saya juga tidak berpikir itu solusi yang ideal.
Idan Shechter
12
@IdanShechter akan lebih baik untuk memberi tahu alasan mengapa Anda menganggap ini bukan solusi yang ideal
Omu
2
Utas bisa bermasalah, karena bukan HttpRequest, beberapa data yang melibatkan HttpRequest bisa nol. Sebagai Contoh, HttpRequest .ApplicationPath. Jika tugas ditulis dengan benar, itu akan berhasil. Masalah lainnya adalah restart pool aplikasi. Jika pool terlalu sering dinyalakan kembali (memori bocor ...), pekerja tidak akan pernah berlari.
Tomas Kubes
2
Jika Anda memiliki beberapa instance berjalan (misalnya load balancing) - mungkin Anda tidak ingin solusi ini (beberapa tugas melakukan hal yang sama)
Illidan
8

Gunakan Penjadwal Windows untuk menjalankan halaman web.

Untuk mencegah pengguna jahat atau spider mesin pencari untuk menjalankannya, ketika Anda mengatur tugas yang dijadwalkan, cukup panggil halaman web dengan querystring, yaitu: mypage.aspx? Dari = dijadwalkantask

Kemudian di halaman memuat, cukup gunakan kondisi: if (Request.Querystring ["from"] == "dijadwalkantask") {// executetask}

Dengan cara ini, tidak ada spider mesin pencari atau pengguna jahat yang dapat menjalankan tugas yang dijadwalkan.

philberg
sumber
5
Lebih baik lagi, gunakan algoritma hashing asin yang benar-benar memverifikasi querystring dengan keamanan sedikit lebih dari frase ajaib. Req akan berupa sesuatu seperti mypage.aspx? Salt = foo & hash = 1223523jbhdgu13t1. Anda hanya perlu memiliki algoritma hashing yang sama di kedua server dan klien. Tambahkan juga batas keras di server; simpan ketika dijalankan dan mencegah dari mengeksekusi terlalu cepat. Saya mungkin paranoid.
Nenotlep
14
Bahkan lebih aman, gunakan Penjadwal Windows untuk menjalankan halaman web yang memeriksa apakah permintaan datang dari server itu sendiri: Request.IsLocal>> hanya server itu sendiri yang dapat menjalankan tugas yang dijadwalkan, tidak ada orang lain.
Konspirasi
Apakah Anda memiliki lebih banyak pengalaman dari pendekatan Anda? Saya akan mengembangkan layanan sejenis dari aplikasi kami dan sekarang saya tidak bisa memutuskan apakah lebih baik memanggil halaman dengan tugas atau cron yang dijadwalkan, atau apakah akan menggunakan sistem cache.
JayDee
3

Selain itu, jika aplikasi Anda menggunakan SQL SERVER Anda dapat menggunakan Agen SQL untuk menjadwalkan tugas Anda. Di sinilah kami biasanya memasukkan kode yang muncul kembali yang didorong oleh data (pengingat email, pemeliharaan terjadwal, pembersihan, dll ...). Fitur hebat yang terintegrasi dengan SQL Agent adalah opsi pemberitahuan kegagalan, yang dapat memberi tahu Anda jika tugas penting gagal.

Zachary
sumber
2

Saya tidak yakin tugas terjadwal seperti apa yang Anda maksud. Jika Anda bermaksud hal-hal seperti "setiap jam, segarkan foo.xml" jenis tugas, kemudian gunakan sistem Tugas Terjadwal Windows. (Perintah "at", atau melalui controller.) Apakah itu menjalankan aplikasi konsol atau meminta halaman khusus yang memulai proses.

Sunting: Saya harus menambahkan, ini adalah cara OK untuk menjalankan aplikasi IIS Anda pada titik yang dijadwalkan juga. Jadi misalkan Anda ingin memeriksa DB Anda setiap 30 menit dan mengirimkan email kepada pengguna tentang beberapa data, Anda dapat menggunakan tugas yang dijadwalkan untuk meminta halaman ini dan karenanya mendapatkan hal-hal pemrosesan IIS.

Jika kebutuhan Anda lebih kompleks, Anda dapat mempertimbangkan untuk membuat Layanan Windows dan menjalankannya untuk melakukan proses apa pun yang Anda butuhkan. Ini juga bermanfaat memisahkan kode untuk tujuan penskalaan atau manajemen. Pada sisi negatifnya, Anda perlu berurusan dengan layanan Windows.

MichaelGG
sumber
2

Jika Anda memiliki server, Anda harus menggunakan penjadwal tugas windows. Gunakan AT /? dari baris perintah untuk melihat opsi.

Kalau tidak, dari lingkungan berbasis web, Anda mungkin harus melakukan sesuatu yang tidak menyenangkan seperti mengatur mesin yang berbeda untuk membuat permintaan ke halaman tertentu pada interval waktu.

t3rse
sumber
2

Saya telah menggunakan Abidar dengan sukses dalam proyek ASP.NET (inilah beberapa informasi latar belakang ).

Satu-satunya masalah dengan metode ini adalah bahwa tugas tidak akan berjalan jika aplikasi web ASP.NET diturunkan dari memori (mis. Karena penggunaan yang rendah). Satu hal yang saya coba adalah membuat tugas untuk menekan aplikasi web setiap 5 menit, menjaganya tetap hidup, tetapi ini tampaknya tidak berfungsi dengan baik, jadi sekarang saya menggunakan scheduler Windows dan aplikasi konsol dasar untuk melakukan ini sebagai gantinya.

Solusi ideal adalah membuat layanan Windows, meskipun ini mungkin tidak mungkin (mis. Jika Anda menggunakan lingkungan hosting bersama). Ini juga membuat segalanya sedikit lebih mudah dari perspektif pemeliharaan untuk menjaga hal-hal dalam aplikasi web.

Mun
sumber
1

Inilah cara lain:

1) Buat skrip web "detak jantung" yang bertanggung jawab untuk meluncurkan tugas-tugas jika tugasnya DUE atau terlambat untuk diluncurkan.

2) Buat proses terjadwal di suatu tempat (lebih disukai di server web yang sama) yang mengenai skrip web dan memaksanya untuk berjalan pada interval reguler. (mis. Windows menjadwalkan tugas yang secara diam-diam meluncurkan skrip heatbeat menggunakan IE atau apa saja)

Fakta bahwa kode tugas terkandung dalam skrip web adalah murni demi menjaga kode dalam basis kode aplikasi web (asumsinya adalah bahwa keduanya saling bergantung satu sama lain), yang akan lebih mudah bagi pengembang web untuk mengelola .

Pendekatan alternatif adalah untuk membuat skrip / program server yang dapat dieksekusi yang melakukan semua jadwal bekerja sendiri dan menjalankan executable itu sendiri sebagai tugas yang dijadwalkan. Ini dapat memungkinkan pemisahan secara mendasar antara aplikasi web dan tugas yang dijadwalkan. Oleh karena itu jika Anda memerlukan tugas yang dijadwalkan untuk berjalan bahkan di aplikasi web / database yang mungkin turun atau tidak dapat diakses, Anda harus pergi dengan pendekatan ini.

Matias Nino
sumber
1
@Matias, Mengapa tidak hanya dijadwalkan saja melakukan pekerjaan yang sebenarnya?
LukeH
1

Anda dapat dengan mudah membuat Layanan Windows yang menjalankan kode pada interval menggunakan metode 'ThreadPool.RegisterWaitForSingleObject'. Ini benar-benar licin dan cukup mudah diatur. Metode ini adalah pendekatan yang lebih ramping kemudian menggunakan Timers dalam Kerangka.

Lihat tautan di bawah untuk informasi lebih lanjut:

Menjalankan Proses Berkala di .NET menggunakan Layanan Windows: http://allen-conway-dotnet.blogspot.com/2009/12/running- periodic-process-in-net-
using.html

atconway
sumber
0

Kami juga menggunakan aplikasi konsol. Jika Anda menggunakan alat logging seperti Log4net, Anda dapat memantau eksekusi dengan benar. Juga, saya tidak yakin bagaimana mereka lebih sulit untuk dipelihara daripada sebuah halaman web, mengingat Anda mungkin berbagi beberapa pustaka kode yang sama antara keduanya jika dirancang dengan benar.

Jika Anda menentang menjalankan tugas-tugas tersebut berdasarkan waktu, Anda dapat memiliki halaman web di bagian administratif situs web Anda yang bertindak sebagai antrian. Pengguna mengajukan permintaan untuk menjalankan tugas, itu pada gilirannya menyisipkan catatan datestamp kosong pada tabel MyProcessQueue dan tugas terjadwal Anda memeriksa setiap X menit untuk catatan baru di MyProcessQueue. Dengan begitu, itu hanya berjalan ketika pelanggan ingin menjalankannya.

Semoga saran itu membantu.

Kyle B.
sumber
0

Salah satu opsi adalah mengatur layanan windows dan memanggilnya untuk melakukan tugas yang dijadwalkan.

Dalam winforms saya telah menggunakan Timers put tidak berpikir ini akan bekerja dengan baik di ASP.NET

AJM
sumber
-1

Perpustakaan Kelas Penjadwal Tugas Baru untuk .NET

Catatan: Sejak perpustakaan ini dibuat, Microsoft telah memperkenalkan penjadwal tugas baru (Penjadwal Tugas 2.0) untuk Windows Vista. Pustaka ini adalah pembungkus untuk antarmuka Penjadwal Tugas 1.0, yang masih tersedia di Vista dan kompatibel dengan Windows XP, Windows Server 2003 dan Windows 2000.

http://www.codeproject.com/KB/cs/tsnewlib.aspx

Ali
sumber
Tolong hapus. Sudah dijawab di bawah ini. Duplikat
Fandango68