Pemicu kuarsa berdasarkan keberadaan file?

Saya sangat baru dalam menggunakan Quartz dan saya memiliki pertanyaan tentang pemicunya. Apakah mungkin untuk memicu berdasarkan keberadaan file? Saya ingin Quartz menjalankan pekerjaan hingga file tertentu ditemukan, lalu berhenti menjalankan pekerjaan itu dan mungkin beralih ke pekerjaan lain.

Misalnya, saya ingin melakukan sesuatu seperti ini:

(1) Job1 memeriksa apakah File.txt ada di direktori tertentu setiap 60 detik.

(2) Jika File.txt ditemukan, picu Job2 untuk memulai. Job1 berhenti memeriksa keberadaan file.

Saat ini, saya punya:

// Job definitions
var Job1 = JobBuilder.Create<TestEmail>().WithIdentity("job1", "group1").Build();
var Job2 = JobBuilder.Create<TestFileTrigger>().WithIdentity("job2", "group2").Build();

// Triggers
ITrigger trigger1 = TriggerBuilder.Create()
      .WithIdentity("trigger1", "group1").StartNow()
      .WithSimpleSchedule(x => x.WithIntervalInSeconds(5).RepeatForever())
      .Build();

ITrigger trigger2 = TriggerBuilder.Create()
      .WithIdentity("trigger2", "group2").StartNow()
      .Build();

// Schedule jobs
scheduler.ScheduleJob(Job1, trigger1);
if (TestFileTrigger.fileExistence == true) 
{
     scheduler.ScheduleJob(Job2, trigger2);
}

tapi sepertinya Job2 tidak pernah dimulai.

TestEmail dan TestFileTrigger cukup mencetak ke konsol saat ini. Boolean TestFileTrigger.fileExistence berasal dari pemeriksaan apakah suatu file ada di lokasi tertentu (yang memang ada).

Sunting: TestFileTrigger.fileExistence adalah boolean. Menambahkan definisi Job1/Job2 jika itu membantu.

Sunting: Saya menemukan bahwa jika saya meletakkan Thread.Sleep(TimeSpan.FromSeconds(x)); sebelum pernyataan if, pernyataan if akan berjalan jika kondisinya terpenuhi. (Di mana x adalah beberapa detik.) Mengapa ini berhasil dalam kasus ini, namun tidak sebaliknya? Saya tidak selalu tahu berapa detik yang diperlukan agar kondisi tersebut terpenuhi.


person user2424607    schedule 30.06.2014    source sumber
comment
Apa yang getnextfiretime katakan? quartz-scheduler.org/ api/2.0.0/org/quartz/   -  person SpaceBison    schedule 01.07.2014
comment
Saya menemukan bahwa jika saya meletakkan Thread.Sleep(TimeSpan.FromSeconds(x)); setelah baris pertama, ini akan dilanjutkan ke loop if (di mana x adalah beberapa detik). getnextfiretime mengembalikan waktu pengaktifan berikutnya yang benar untuk pemicu.   -  person user2424607    schedule 01.07.2014


Jawaban (2)


Sepertinya Anda tidak memahami konkurensi dan threading yang terlibat di sini.

Masalahnya adalah sebagai berikut.

Utas UTAMA Anda melakukan hal berikut.

  1. Ciptakan dua pekerjaan
  2. Berikan pemicu pada setiap pekerjaan
  3. Jadwalkan Job1 untuk memulai
  4. Centang TestFileTrigger.fileExistence dan jika benar, jalankan Job2 (salah agar tidak berjalan).

MAKA thread threadpool akan memulai Job1. Kemungkinan besar pengaturan TestFileTrigger.fileExistence = true. Tapi thread utama telah menyelesaikan pekerjaannya.

SIRIP.

Anda tidak boleh kembali dan memeriksa apakah TestFileTrigger.fileExistence benar. Jadi hasilnya tidak relevan. Anda sebenarnya memeriksa hasilnya SEBELUM Anda mendapatkan hasil.

Dengan menambahkan Thread.Sleep Anda memberi pekerjaan1 cukup waktu untuk diselesaikan dan memberi Anda hasil (pekerjaan1 berjalan secara asinkron dan bersamaan, dan jelas Anda mengharapkannya berjalan secara sinkron). Bayangkan misalnya Anda menyuruh teman Anda Fred pergi ke toko untuk membeli Pizza dan meletakkannya di meja Anda (asynchronous), lalu langsung berbalik dan bertanya-tanya mengapa tidak ada pizza di meja Anda.

Sinkronisasinya adalah jika Anda sendiri pergi ke toko, membeli pizza dan membawanya pulang dan meletakkannya di meja Anda, LALU makan pizza dari meja Anda.

JobScheduler.ScheduleJob(job1, trigger1); berfungsi secara asinkron.

Anda harus membuat pekerjaan untuk menyelesaikan langkah 4 dan menjadwalkannya untuk dijalankan secara berkala, ATAU Anda menggunakan FileScanJob bawaan sebagai gantinya.

person Aron    schedule 02.07.2014
comment
Jadi begitu. Apakah ada cara untuk menghentikan pekerjaan setelah kondisinya terpenuhi? Misalnya, saya punya: Job1 memeriksa apakah ada file. Jika ya, setel fileExistence == true. Pekerjaan2 periksa apakah fileExistence == benar. Jika ya, lakukan sesuatu. Apakah ada cara untuk menghentikan pekerjaan setelah file ada? Ada scheduler.DeleteJob, tapi saya tidak yakin di mana saya akan menaruhnya. Di dalam Job1 dan Job2? Di dalam Utama? Jika saya memahami konkurensi dengan benar, saya tidak dapat memasang loop if setelah menjadwalkan pekerjaan kecuali saya menggunakan Thread.Sleep. Tapi saya tidak tahu berapa lama sampai file tiba dan kondisi berhenti terpenuhi. - person user2424607; 02.07.2014
comment
Saya berpikir bahwa Quartz adalah cara yang salah untuk melakukan ini. Anda mencoba memicu suatu peristiwa dan bukan jadwal. Quartz adalah penjadwal, dan karenanya menyesuaikannya dengan kebutuhan Anda cukup sulit. Saya pribadi akan menggunakan FileSystemWatcher. - person Aron; 02.07.2014
comment
Ya saya setuju. Terima kasih telah menyarankan FileSystemWatcher, sepertinya cara yang lebih baik untuk melakukan ini! Saya pasti akan mencoba menggunakannya. Di sisi lain, apakah JobChaining akan menjadi alternatif potensial? - person user2424607; 02.07.2014

jenis aplikasi apa ini?

Jika ini, misalnya, layanan Windows - untuk menjaga penjadwal tetap hidup sehingga dapat menjalankan pekerjaan sesuai dengan pemicu Anda, Anda perlu melakukan sesuatu seperti:

ThreadStart start = SetupSchedules()
var thread = new Thread(start) { Name = "mysvc" }
thread.Start();

.. ini akan masuk ke metode override void OnStart(string[] args) layanan Windows.

Metode SetupSchedules akan menjadi sesuatu yang berhubungan dengan pekerjaan Quartz dan akan menjadi seperti (Kode yang Anda tulis di atas di OP akan menjadi awal yang baik):

ISchedulerFactory factory = new StdSchedulerFactory();
JobScheduler = factory.GetScheduler();
JobScheduler.ScheduleJob(job1, trigger1);

Ini harus membuatnya tetap hidup sehingga dapat menjalankan tugasnya. Saya telah menghilangkan banyak hal di sini, tapi mudah-mudahan ini bisa memberi Anda beberapa petunjuk untuk membantu memasukkannya ke dalam aplikasi Anda.

Anda juga memerlukan sesuatu seperti ini:

private void ManageThread()
{
   var _thread = Thread.CurrentThread;
   while (!_threadMustStop) // false by default, set this to true in a 'shutdown' process
   {
       Thread.Sleep(10000);
   }
}

...yang Anda panggil dari metode SetupSchedules Anda

person SpaceBison    schedule 02.07.2014