none
не появяется TimerJob RRS feed

  • Вопрос

  • Добрый день.Учусь создавать TimerJob'ы , все делаю по инструкции http://www.c-sharpcorner.com/UploadFile/b8e86c/how-to-create-timer-job-in-sharepoint-2013/

    Фича создается, активируется, а  TimerJob не появляется. Никаких ошибок не выдает. Куда копать???

    3 ноября 2016 г. 12:34

Ответы

    1. А как вы узнаете что у вас код отработал? Если будет ошибка при создании джоба, то она проглотится, вы даже не узнаете, что что-то пошло не так.
    2. У меня есть подозрение, что BeginSecond и EndSecond должны быть 0 и 59, а не 1 и 60.
    3. Я не уверен что вы даете корректный name для джоба

    Попробуйте убрать все try\catch, сразу много нового узнаете о своем коде.

    И еще почитайте пост http://blog.gandjustas.ru/2011/10/10/blog-post/


    Business Solutions Architect, SharePoint Expert, Trainer, Speaker and Author http://gandjustas.blogspot.com/ Join Russian SharePoint Community at https://www.facebook.com/groups/sharepointrussian/

    • Помечено в качестве ответа Natalya_35 16 ноября 2016 г. 13:45
    8 ноября 2016 г. 16:12

Все ответы

  • Добрый день.Учусь создавать TimerJob'ы , все делаю по инструкции http://www.c-sharpcorner.com/UploadFile/b8e86c/how-to-create-timer-job-in-sharepoint-2013/

    Фича создается, активируется, а  TimerJob не появляется. Никаких ошибок не выдает. Куда копать???

    Если все сделали как написано, после публикации попробуйте еще раз перезапустить IIS, через CMD 'iisreset/restart' и снова проверить.
    3 ноября 2016 г. 12:38
  • не помогло..( Я уже пробовала из разных источников копи/пастить создание, удаление job, активацию и деакивацию фичи. Но TimerJob не появляется...
    3 ноября 2016 г. 13:18
  • Попробуйте активировать фичу через powershell с параметром -Force.

    Посмотрите логи, возможно выдается Exception при отработке Event Receiver'а фичи. Можно еще попробовать продебажить Event Receiver фичи.

    3 ноября 2016 г. 14:41
  • Добрый день! При добавлении нового Timer Job'а необходимо перезапускать службу таймера SharePoint'а, потому как все джобы находятся в этой службе.
    • Предложено в качестве ответа Alexander Karakulov 4 ноября 2016 г. 18:55
    • Помечено в качестве ответа Alexander RusinovModerator 4 ноября 2016 г. 19:20
    • Снята пометка об ответе Natalya_35 7 ноября 2016 г. 11:29
    4 ноября 2016 г. 18:55
  • Добрый день! При добавлении нового Timer Job'а необходимо перезапускать службу таймера SharePoint'а, потому как все джобы находятся в этой службе.

    Это неверно. Перезапускать надо при удалении, а не добавлении. Потому что .NET не умеет выгружать сборки.

    Надо код и конфигурацию фермы смотреть. Возможно вы хотите посмотреть джобу на сервере, на котором не запущена служба веб-приложений.


    Business Solutions Architect, SharePoint Expert, Trainer, Speaker and Author http://gandjustas.blogspot.com/ Join Russian SharePoint Community at https://www.facebook.com/groups/sharepointrussian/

    4 ноября 2016 г. 22:21
  • Ферма тестовая из 1го сервера.

    EventReceiver:

        public class Feature2EventReceiver : SPFeatureReceiver
        {
            public override void FeatureActivated(SPFeatureReceiverProperties properties)
            {
                try
                {
                    SPSecurity.RunWithElevatedPrivileges(delegate()
                    {
                        SPWebApplication parentWebApp = (SPWebApplication)properties.Feature.Parent;
                        DeleteExistingJob("Timer job lic v2", parentWebApp);
                        CreateJob(parentWebApp);
                    });
                }
                catch (Exception ex)
                {
                    throw ex;
                }
            }
            private bool CreateJob(SPWebApplication site)
            {
                bool jobCreated = false;
                try
                {
                    TimerJobDemo job = new TimerJobDemo("Timer job lic v2", site,null,SPJobLockType.Job);
                    SPMinuteSchedule schedule = new SPMinuteSchedule();
                    schedule.BeginSecond = 1;
                    schedule.EndSecond = 60;
                    schedule.Interval = 15;
                    job.Schedule = schedule;
                    job.Update();
                }
                catch (Exception)
                {
                    return jobCreated;
                }
                return jobCreated;
            }
            public bool DeleteExistingJob(string jobName, SPWebApplication site)
            {
                bool jobDeleted = false;
                try
                {
                    foreach (SPJobDefinition job in site.JobDefinitions)
                    {
                        if (job.Name == jobName)
                        {
                            job.Delete();
                            jobDeleted = true;
                        }
                    }
                }
                catch (Exception)
                {
                    return jobDeleted;
                }
                return jobDeleted;
            }

            public override void FeatureDeactivating(SPFeatureReceiverProperties properties)
            {

                lock (this)
                {
                    try
                    {
                        SPSecurity.RunWithElevatedPrivileges(delegate()
                        {
                            SPWebApplication parentWebApp = (SPWebApplication)properties.Feature.Parent;
                            DeleteExistingJob("Timer job lic v2", parentWebApp);
                        });
                    }
                    catch (Exception ex)
                    {
                        throw ex;
                    }
                }
            }

    Class:

        public class TimerJobDemo : SPJobDefinition
        {

            public TimerJobDemo()
                : base()
            {
            }
            public TimerJobDemo(string name, SPWebApplication wa, SPServer server, SPJobLockType lock1) : base(name, wa, server, lock1) { }
            public TimerJobDemo(string jobName, SPService service) : base(jobName, service, null, SPJobLockType.None)
            {
                this.Title = "Timer job lic v2";
            }
     
              public TimerJobDemo(string jobName, SPWebApplication webapp)
                : base(jobName, webapp, null, SPJobLockType.ContentDatabase)
            {
                this.Title = "Timer job lic v2";
            }
                
            public override void Execute(Guid targetInstanceId)
            {
                using (SPSite site = new SPSite("http://portal"))
                {
                    using (SPWeb web = site.RootWeb)
                    {
                        SPList list = web.Lists["List1"];
                        SPListItem item = list.AddItem();
                        item["Название"] = "Now Its: " + DateTime.Now.ToLongTimeString();
                        item.Update();
                    }
                }
            }
        }
    }

    7 ноября 2016 г. 5:42
  • Вот тут вы создаете объект:

    try
    {
        TimerJobDemo job = new TimerJobDemo("Timer job lic v2", site,null,SPJobLockType.Job);
        SPMinuteSchedule schedule = new SPMinuteSchedule();
        schedule.BeginSecond = 1;
        schedule.EndSecond = 60;
        schedule.Interval = 15;
        job.Schedule = schedule;
        job.Update();
    }

    Судя по коду этот объект в классе TimerJobDemo вызывает конструктор:

    public TimerJobDemo(string name, SPWebApplication wa, SPServer server, SPJobLockType lock1) : base(name, wa, server, lock1) { }

    Но в этом конструкторе не указано имя создаваемого TJ. В таком случае в классе  TimerJobDemo должен быть приблизительно такой конструктор, в замену того, что указано было выше:

    public TimerJobDemo(string name, SPWebApplication wa, SPServer server, SPJobLockType lock1) : base(name, wa, server, lock1)
    { 
        Title = name;
    }

    Получается что вы создаете новый Timer Job без имени, поэтому он и не появляется в списке. 

    Еще в методе public override void Execute(Guid targetInstanceId) порекомендовал бы не писать так как сейчас. В этом методе лучше получить коллекцию сайтов через WebApplication.Sites и там найти нужный сайт. 


    8 ноября 2016 г. 5:42
    1. А как вы узнаете что у вас код отработал? Если будет ошибка при создании джоба, то она проглотится, вы даже не узнаете, что что-то пошло не так.
    2. У меня есть подозрение, что BeginSecond и EndSecond должны быть 0 и 59, а не 1 и 60.
    3. Я не уверен что вы даете корректный name для джоба

    Попробуйте убрать все try\catch, сразу много нового узнаете о своем коде.

    И еще почитайте пост http://blog.gandjustas.ru/2011/10/10/blog-post/


    Business Solutions Architect, SharePoint Expert, Trainer, Speaker and Author http://gandjustas.blogspot.com/ Join Russian SharePoint Community at https://www.facebook.com/groups/sharepointrussian/

    • Помечено в качестве ответа Natalya_35 16 ноября 2016 г. 13:45
    8 ноября 2016 г. 16:12
  • Получается что вы создаете новый Timer Job без имени, поэтому он и не появляется в списке.  


    Name и Title - разные свойства. Title можно не задавать. Задачи без title отображаются в UI со своим Name.

    Business Solutions Architect, SharePoint Expert, Trainer, Speaker and Author http://gandjustas.blogspot.com/ Join Russian SharePoint Community at https://www.facebook.com/groups/sharepointrussian/

    8 ноября 2016 г. 16:14
  • Нет, проблемы была в определении Сайта. Заменила 

    SPWebApplication parentWebApp = (SPWebApplication)properties.Feature.Parent;

    на

        SPWebApplication parentWebApp = SPWebApplication.Lookup(new Uri("http://portal"));

    все заработало

    16 ноября 2016 г. 13:44
  • Но это не универсальный код. А если url поменяется? Или вы захотите перенести решение на другую ферму?

    Какой scope у вашей фичи? Web Application?

    17 ноября 2016 г. 12:21
  • Какой scope у вашей фичи? Web Application?

    Похоже что Site, что неправильно в принципе.

    Business Solutions Architect, SharePoint Expert, Trainer, Speaker and Author http://gandjustas.blogspot.com/ Join Russian SharePoint Community at https://www.facebook.com/groups/sharepointrussian/

    17 ноября 2016 г. 12:23
  • Нет, проблемы была в определении Сайта. Заменила 

    SPWebApplication parentWebApp = (SPWebApplication)properties.Feature.Parent;

    на

        SPWebApplication parentWebApp = SPWebApplication.Lookup(new Uri("http://portal"));

    все заработало

    *facepalm*

    http://blog.gandjustas.ru/2011/10/10/blog-post/

    Цитирую себя:

    Важно. Если вы попытаетесь добавить задачу таймера в фиче уровня Site или Web, то при деплое из Visual Studio оно сработает, а при попытке активировать фичу из веб-интерфейса упадет. Это новое ограничение SharePoint 2010, не позволяющее делать Update для классов наследников SPPersistedObject из контекста веб-приложения.


    Business Solutions Architect, SharePoint Expert, Trainer, Speaker and Author http://gandjustas.blogspot.com/ Join Russian SharePoint Community at https://www.facebook.com/groups/sharepointrussian/

    17 ноября 2016 г. 12:25