我是第一次写计时器工作.我正在关注可以通过谷歌搜索获得的示例作为我的参考.
在许多此类文章中,我遇到了计时器作业功能被激活到网站集级别或站点级别.
我觉得这很奇怪,因为特定的Web应用程序只能有一个计时器作业实例.
是不是所有计时器作业功能都应限定为Web应用程序?
我在这里错过了什么吗?
我正在创建我的第一个Timer Job并想要调试它.我已经通过一个功能安装了计时器作业,并将其添加到webapplication的JobDefinitions集合中,并添加了一个SPMinuteSchedule,每5分钟运行一次(用于测试目的).
然后,在Visual Studio中,我尝试将调试器附加到WebApplication的Process,Central Admin进程和OWSTIMER.exe进程,但它不会调试到TimerJob的Execute方法.我在这里想念的是什么
PS计时器作业状态显示成功,因此正在运行.奇怪的...
关于使用ScheduledThreadPoolExecutor执行某些重复任务,我正在跟进一个有趣的问题.
调度此对象将返回ScheduledFuture对象,可以使用该对象取消下一次任务运行.
这里要注意的一件事是任务本身与时间表完全脱钩 -
ScheduledExecutorService executor = new ScheduledThreadPoolExecutor(1);
ScheduledFuture nextSchedule =
executor.schedule(task, 60000, TimeUnit.MILLISECONDS);
Run Code Online (Sandbox Code Playgroud)
哪里-
SomeTask task = new SomeTask();
Run Code Online (Sandbox Code Playgroud)
所以任务本身并不了解时间表.如果有办法让任务取消并为自己创建一个新的时间表,请启发.
谢谢
我有一个计时器工作,我想每天只运行一次,为整个农场.我如何能
我们有一个SP计时器工作,运行良好一段时间.最近,管理员将另一台服务器加入了服务器场,因此SharePoint决定开始在另一台服务器上运行此计时器作业.问题是服务器上没有安装所有依赖项(即Oracle),因此作业失败.我只是在寻找阻力最小的路径.我的问题是有一种方法可以强制计时器作业在你想要的服务器上运行吗?
[编辑] 如果我可以通过适用于我的代码来完成.我只需要知道API是什么,如果确实存在的话.
我在Web应用程序中创建了一个网站集,其中用户A作为网站集管理员.我在网站功能页面中添加了一个链接.点击该链接,我正在尝试创建一个计时器作业.下面是单击该链接时执行的代码
//Allow unsafe updates.
SPContext.Current.Web.AllowUnsafeUpdates = true;
//Get current web application.
SPWebApplication webApp = SPContext.Current.Site.WebApplication;
// Create new job.
ArchiveJob automaticArchiveJob = new ArchiveJob(scheduleDetails.scheduleName, webApp);
SPHourlySchedule hourlySchedule = new SPHourlySchedule();
hourlySchedule.BeginMinute = 0;
hourlySchedule.EndMinute = 1;
automaticArchiveJob.Schedule = hourlySchedule;
//Finally update archival job.
automaticArchiveJob.Update();
Run Code Online (Sandbox Code Playgroud)
现在,当我使用用户A登录并单击"站点设置"页面上的该链接时,我收到一条安全例外,其中包含"拒绝访问"消息automaticArchiveJob.Update()
.但是,如果我使用管理员用户登录(我也使用此用户登录到该计算机)并单击该链接,则会成功创建作业.此外,我使用户成为WSS_ADMIN_WPG
组的成员,但仍然遇到同样的问题.我还需要做些什么来解决这个问题.
我目前正在研究一种可以进行网站集管理的TimerJob.当作业运行时,它会查找列表以检索网站集的Url,然后调用SPSite.Exists()
以检查该网站是否仍然存在.
为了测试TimerJob,我删除了一个网站集,但是在列表中留下了相应的条目.然后我启动TimerJob并在调试模式中逐步执行其代码.当涉及到检查站点是否存在的点SPSite.Exists()
返回true.
当我第二次为同一网站集运行TimerJob时,该SPSite.Exists()
方法返回false.
所以现在我想知道为什么SPSite.Exists()
当我第一次运行这个工作时返回错误的结果.这可能是由缓存引起的吗?
当我在TimerJob之外运行相同的代码时,每次都SPSite.Exists()
返回正确的结果.
UPDATE
所以我做了一些调试,看起来这个问题确实是由一些缓存机制造成的,因为在删除测试网站集之后和TimerJob启动之前重新启动Windows SharePoint Services定时服务时不会发生这种情况.
目前我无法想象另一种解决方案,而不是尝试访问已删除的网站并捕获将被抛出的异常,以确定该网站是否真的存在.
更新2
经过一些测试后,我意识到重新启动定时器服务后第一次调用SPSite.Exists()(在TimerJob中)时不会出现问题.第二次调用(针对不同的网站集)仍会导致已知问题.
更新3
目前我正在使用一个丑陋的黑客来解决我的问题.当SPSite.Exists()返回true但它实际上不存在时,我创建一个SPSite对象并尝试通过调用其Usage属性来激发FileNotFoundException.当异常出现时,我知道该网站不存在.抛出异常后奇怪的是,SPSite.Exists()返回正确的结果(false).
还有其他建议吗?
再见,弗洛
我有一个计时器作业,已部署到具有多个Web前端的服务器.
但问题是这个计时器工作不会每天被调用.我已经在计时器作业的Execute()方法中实现了事件记录,但是我没有看到生成任何日志.
有关什么可能导致计时器作业无法被SharePoint定时服务执行的任何想法?我该如何解决这个问题?
在多个前端的服务器中运行计时器作业是否有"问题"?计时器作业是否会在所有Web前端或其中任何一个中执行?如何知道哪台机器有我的事件日志?
这可能是一个愚蠢的问题,但是有多个前端进行负载均衡会影响分层对象存储的行为方式吗?
编辑:
其中一位评论者Sean McDounough(感谢Sean !!)提出了一个非常好的观点:
"计时器作业是否在所有WFE上运行将是您在构造函数中指定的SPJobLockType枚举值的函数.使用值"无"表示作业将在所有WFE上运行."
现在,我的计时器作业负责将定期邮件发送到用户列表.目前它被标记为SPJobLockType.Job"
如果我将其更改为SPJobLockType.None,这是否意味着我的计时器作业将分别在所有WFE中执行?(这是不希望的,它会通过多封电子邮件向所有用户发送垃圾邮件)
或者是否意味着计时器作业将在任何一个WFE中执行,是否是任意的?
我们可以在SharePoint计时器作业中使用SPSecurity.RunWithElevatedPrivileges吗?
在其身份下,计时器作业是否在提升的特权下运行?
任何问题,必须知道有关这方面的事实也将不胜感激.
我有一个SharePoint计时器作业,需要配置列表存在于网站集的特定位置.如果该列表不存在,我想向用户表明,以便他们可以创建(并填充当然)所述列表并重新运行该作业.
我可以使用下面的代码写入事件日志,我知道我可以抛出异常来指示失败的作业状态,但我想要做的是抛出一个异常,并带有一条消息,指出问题的方式不是要求查看ULS或访问事件日志.到目前为止,我已经找到了帖子这样一个和这一个没有太多细节.
所以有两个问题:1)有没有办法为计时器作业异常提供失败消息?2)抛出比Exception()更好的选择吗?
缺少网站集时使用的事件日志记录
SPDiagnosticsService.Local.WriteEvent(0,
new SPDiagnosticsCategory("MyCategory",
TraceSeverity.Unexpected,
EventSeverity.ErrorCritical),
EventSeverity.ErrorCritical,
"Assert failed: if (!spweb.Exists)" + sp.Url,
sp.ToString());
Run Code Online (Sandbox Code Playgroud)
我想用丢失的配置列表做什么
bool configListExists = ListExists(spweb, ConfigListName);
if (! configListExists)
{
ReportMissingConfigList();
throw new Exception("Configuration list not found");
}
public static bool ListExists(SPWeb web, string listName)
{
return web.Lists.Cast<SPList>().Any(list => string.Equals(list.Title, listName));
}
Run Code Online (Sandbox Code Playgroud)