【问题标题】:When deleting timer job it throws error 'Object reference not set to an instance of an object'删除计时器作业时,它会引发错误“对象引用未设置为对象的实例”
【发布时间】:2015-03-04 14:25:28
【问题描述】:

我使用以下代码创建了一个计时器作业:

namespace EmployeeDemo
{
    class DeleteEmployees : SPJobDefinition
    {
        public DeleteEmployees() : base() { }

        public DeleteEmployees(string jobName, SPWebApplication webapp)
            : base(jobName, webapp, null, SPJobLockType.ContentDatabase)
        {
            this.Title = "Delete Employees Timer Job";
        }

        public override void Execute(Guid targetInstanceId)
        {
            // Code
        }
    }
}

然后我创建了一个网站范围的功能。在其事件接收器中,停用时,我有以下代码:

const string timerJobName = "Delete Employees Timer Job";
public override void FeatureDeactivating(SPFeatureReceiverProperties properties)
{
    DeleteJob(properties.Feature.Parent as SPSite);
}
private void DeleteJob(SPSite site)
{
    foreach (SPJobDefinition job in site.WebApplication.JobDefinitions)
    {
        if (job.Name == timerJobName)
        {
            job.Delete();
        }
    }
}

但它给我带来了错误。通过调试,我了解到错误是在job.Delete(); 行上引发的。错误是:

对象引用未设置为对象的实例。

这让我有点困惑,因为 job.Name 语句完美执行,甚至为我提供了正确的计时器作业对象。但是在尝试删除作业时,它会引发错误。

我发现this question 与我的问题相似,但这些建议对我不起作用。从this discussion 我尝试在SPSecurity.RunWithElevatedPrivileges 中编写删除代码,但它仍然不适合我。

有谁知道为什么会发生这种情况以及如何解决这个问题?

更新 1

更多细节。

NullReferenceException 未被用户代码处理

对象引用未设置为对象的实例。

这是堆栈跟踪

   at Microsoft.SharePoint.Administration.SPConfigurationDatabase.DeleteObject(Guid id)
   at Microsoft.SharePoint.Administration.SPConfigurationDatabase.Microsoft.SharePoint.Administration.ISPPersistedStoreProvider.DeleteObject(SPPersistedObject persistedObject)
   at Microsoft.SharePoint.Administration.SPPersistedObject.Delete()
   at Microsoft.SharePoint.Administration.SPJobDefinition.Delete()
   at EmployeeDemo.Features.DeleteEmpFeature.DeleteEmpFeatureEventReceiver.DeleteJob(SPSite site)
   at EmployeeDemo.Features.DeleteEmpFeature.DeleteEmpFeatureEventReceiver.FeatureDeactivating(SPFeatureReceiverProperties properties)
   at Microsoft.SharePoint.SPFeature.DoActivationCallout(Boolean fActivate, Boolean fForce)

【问题讨论】:

  • 如果异常确实是由job.Delete() 抛出的,那么它应该在Delete 方法内的某个地方抛出。仅仅因为如果job 为null - 将在job.Name 前一行抛出异常。因此,您必须查看您尚未向我们展示的 Delete 方法。
  • @AndyKorneyev:Delete() 方法属于SPJobDefinition 类。它来自 SharePoint API,所以我想我看不到它的源代码,或者我可以吗?
  • 嗯,其实你可以。例如,通过使用 .NET Reflector 或其他类似工具。但在探索该来源之前 - 确保它恰好是 job.Delete 引发异常,而不是之前的某行(可能是 site.WebApplication.JobDefinitions 的某些部分?)。对我来说,某些 Microsoft API 方法不太可能在没有任何明显原因的情况下抛出 NullReferenceException。
  • 扩展安迪的 cmets:如果您认为这不仅仅是 the canonical NullReferenceException question 的欺骗,您的问题需要包含更多细节。至少,您需要提供有关异常本身的完整详细信息:异常名称和完整堆栈跟踪,以及消息(您已经提供并且我们可以从中推断出实际异常,但您应该无论如何都要提供)。
  • @PeterDuniho:我已按照您的要求添加了错误详细信息。

标签: c# sharepoint sharepoint-2010 timer-jobs


【解决方案1】:

要删除作业,请使用 powershell:

$jobToDelete = Get-SPTimerJob -WebApplication "http://intranet" -Identity "YourJobName"
$jobToDelete.Delete()

然后运行:

iisreset /noforce

在配置数据库中,您需要授予这些权限才能让删除工作:

use [Sharepoint_Config]
GO
GRANT EXECUTE ON [dbo].[proc_putObjectTVP] TO [WSS_Content_Application_Pools]
GRANT EXECUTE ON [dbo].[proc_putObject] TO [WSS_Content_Application_Pools]
GRANT EXECUTE ON [dbo].[proc_putDependency] TO [WSS_Content_Application_Pools]
GRANT EXECUTE ON [dbo].[proc_putClass] TO [WSS_Content_Application_Pools]
GRANT EXECUTE ON [dbo].[proc_getNewObjects] TO [WSS_Content_Application_Pools]
GRANT EXECUTE ON [dbo].[proc_dropObject] TO [WSS_Content_Application_Pools]
GO

【讨论】:

    猜你喜欢
    • 2016-05-24
    • 2011-07-09
    • 2012-08-31
    • 2011-11-21
    • 2012-10-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多