我将以下代码设置为预定任务:
public class OptimizeDatabase : IJob {
#region Constructor
public OptimizeDatabase(DataContext dataContext) {
DbContext = dataContext;
}
#endregion
#region Fields
private readonly DataContext DbContext;
#endregion
#region Methods
public async Task Execute() {
Stopwatch stopWatch = new Stopwatch();
stopWatch.Start();
string result = "Ok";
try {
// Rebuild Indexes
DbContext.Database.ExecuteSqlCommand("EXEC sp_MSforeachtable \"ALTER INDEX ALL ON ? REBUILD WITH (ONLINE=OFF)\"");
// Update Statistics
DbContext.Database.ExecuteSqlCommand("EXEC sp_updatestats;");
}
catch (Exception ex) {
result = ex.Message + Environment.NewLine + ex.StackTrace;
}
stopWatch.Stop();
DbContext.TaskLogs.Add(new TaskLog {
Date = DateTime.Now,
ElapsedSeconds = stopWatch.Elapsed.TotalSeconds,
Result = result,
Task = "Optimize Database"
});
await DbContext.SaveChangesAsync();
}
#endregion
}
它已配置为在Startup.cs中运行
RecurringJob.AddOrUpdate<OptimizeDatabase>(x => x.Execute(), Cron.Daily(10));
所有其他计划任务执行都没有问题,但是,该任务总是引发以下错误:
超时已过期。在完成之前,超时时间已过 操作或服务器无响应。在 System.Data.SqlClient.SqlConnection.OnError(SqlException异常, 布尔值breakConnection,动作为1 wrapCloseInAction)
任何想法或见解都会受到赞赏。
答案 0 :(得分:0)
超时问题是因为其中一个查询花费的时间更长。
据我所知,.Net中有2个超时,即连接超时(ConnectionTimeout Property)和命令超时(CommandTimeout Property)。这两个超时的默认时间均为30秒。
我建议您:
使用部分代码,所做的更改将类似于:
try {
// Change CommandTimeout
DbContext.Database.CommandTimeout = 120;
// Rebuild Indexes
DbContext.Database.ExecuteSqlCommand("EXEC sp_MSforeachtable \"ALTER INDEX ALL ON ? REBUILD WITH (ONLINE=OFF)\"");
// Update Statistics
DbContext.Database.ExecuteSqlCommand("EXEC sp_updatestats;");
}
catch (Exception ex) {
result = ex.Message + Environment.NewLine + ex.StackTrace;
}
您可以看一下这篇文章,它解释了一个可能的超时原因https://stackoverflow.com/a/8603111/2654879的好方案。
我希望这个答案可以帮助您解决这个问题。
此致
JB