开发者

How to use Quartz .net in Windows form?

开发者 https://www.devze.com 2023-02-12 05:24 出处:网络
i try to write a project to use Quart.net (http://quartznet.sourceforge.net/) to make job scheduling system (Quartz.NET is a full-featured, open source job scheduling system that can be used from smal

i try to write a project to use Quart.net (http://quartznet.sourceforge.net/) to make job scheduling system (Quartz.NET is a full-featured, open source job scheduling system that can be used from smallest apps to large scale enterprise systems.) But i can not use listbox1.items add in execute method. How can use windows form controls is Quartz?

using System.Threading;
using Quartz;
using Quartz.Impl;

namespace QuartzTest1
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
        }

       private void btnStart_Click(object sender, Eve开发者_开发百科ntArgs e)
        {
            ISchedulerFactory schedFact = new StdSchedulerFactory();

            //Yeni bir zamanlayıcı oluşturulup çalıştırılıyor
            IScheduler sched = schedFact.GetScheduler();
            sched.Start();

            //Oluşturduğumuz görev(MyJob) hazırlanıyor

            JobDetail jobDetail = new JobDetail("myJob", null, typeof(MyJob));

            //Başlatıldıktan 20 sn sonra çalışacak bir SimpleTrigger oluşturuluyor. 
            //İlk çalışmadan sonra 10 sn arayla 5 kez daha tetiklenecek
            Trigger trigger = new SimpleTrigger("myFirstTrigger",
                                                   null,
                                                   DateTime.UtcNow.AddSeconds(20),
                                                   null,
                                                   5,
                                                   TimeSpan.FromSeconds(10));

            //Görev tetikleyici ile zamanlanıyor
            sched.ScheduleJob(jobDetail, trigger);
            //Uygulama bekletiliyor
            ManualResetEvent resetEvent = new ManualResetEvent(false);
            resetEvent.WaitOne();
        }
    }

    public class MyJob :Form1, IJob
    {

        public void Execute(JobExecutionContext context)
        {
            listBox1.Invoke(new Action(delegate()
            {
                listBox1.Items.Add(String.Format("Görev çalıştırıldı : {0}", DateTime.Now.ToString("dd.MM.yyyy HH:mm:ss")));
            }));

        }
    }
}

How to use below codes:


 public void Execute(JobExecutionContext context)
        {
            listBox1.Invoke(new Action(delegate()
            {
//.....
//...
//..
//.


ERROR:

InvalidOperationException: Invoke or BeginInvoke can not be called on Window handler until the creation of the audit.


OK!

I have wasted too much time with this issue making Quartz.net working on windows form.

BUT, I have a Generic solution which I hope will help others.

  1. Create the IJOB class as you normally do

  2. Create a static pointer to the form

  3. In the main form have a public function called something like:

    public void Execute()
    public delegate void ExecuteCallback();
    
  4. On Execute, check to see if "Invoke is Required"

  5. Construct the delegate, and call Invoke.

Then hopefully all the threading issues see to be removed, you can call any controls, you can reschedule a Quartz job ,etc.

public class RunMyTask: IJob
{

    public static SalesBuddy.Form1 CurrentForm = null;

    public RunMyTask()
    {
    }

    public void Execute(IJobExecutionContext context)
    {
        if (CurrentForm.InvokeRequired)
        {
            SalesBuddy.Form1.ExecuteCallback x = new SalesBuddy.Form1.ExecuteCallback(CurrentForm.Execute);
            CurrentForm.Invoke(x);

        }
        else
        {
            CurrentForm.Execute();
        }
    }


Quartz.net instantiate job objects based on the passed in type. In your code:

JobDetail jobDetail = new JobDetail("myJob", null, typeof(MyJob));

when you then try to call:

listBox1.Invoke(new Action(delegate()
            {
                listBox1.Items.Add(String.Format("Görev çalıştırıldı : {0}", DateTime.Now.ToString("dd.MM.yyyy HH:mm:ss")));
            }));

You are executing this on a freshly created instance of a form in another thread (quartz.net executes jobs in a predefined amount of workerthreads) that is not displayed, that's why you are getting the error.

To prevent this you should not call the UI code in your Job, do not derive the job from Form1. Enable communication between UI and job via some sort of observer pattern e.g. EventAggregator.

0

精彩评论

暂无评论...
验证码 换一张
取 消

关注公众号