나는 SO를 검색하고 Quartz.net에 대한 답변을 찾았습니다. 하지만 내 프로젝트에는 너무 큰 것 같습니다. 동등한 솔루션을 원하지만 더 간단하고 코드 내에서 (외부 라이브러리가 필요하지 않음). 매일 특정 시간에 메소드를 호출하려면 어떻게해야합니까?
이에 대한 몇 가지 정보를 추가해야합니다.
- 이 작업을 수행하는 가장 간단하고 추악한 방법은 매초 / 분마다 시간을 확인하고 적절한 시간에 메서드를 호출하는 것입니다.
나는 이것을하기위한보다 효과적인 방법을 원하고, 시간을 지속적으로 확인할 필요가 없으며, 작업이 완료되지 않았는지 여부를 제어 할 수 있습니다. 방법이 실패하면 (문제로 인해), 프로그램은 로그 쓰기 / 이메일 보내기를 알아야합니다. 그래서 작업을 예약하는 것이 아니라 메서드를 호출해야합니다.
이 솔루션을 찾았 습니다 Java 의 Java 에서 고정 시간에 메서드 호출 . C #에도 비슷한 방법이 있습니까?
편집 : 나는 이것을했다. void Main ()에 매개 변수를 추가하고이 매개 변수로 프로그램을 실행하기 위해 bat (Windows 작업 스케줄러에 의해 예약 됨)를 만들었습니다. 프로그램이 실행되고 작업을 수행 한 다음 종료됩니다. 작업이 실패하면 로그를 작성하고 이메일을 보낼 수 있습니다. 이 접근 방식은 내 요구 사항에 잘 맞습니다. 🙂
답변
- 원하는 작업을 수행하는 콘솔 앱 만들기
- Windows ” 예약 된 작업 “기능을 사용하여 실행에 필요한 시간에 해당 콘솔 앱을 실행하도록합니다.
그게 정말 필요한 전부입니다!
업데이트 : 앱 내에서이 작업을 수행하려면 몇 가지 옵션이 있습니다.
- A의 윈도우 폼의 응용 프로그램, 당신은 활용할 수있는
Application.Idle
이벤트와 당신의 메소드를 호출 할 수있는 일의 시간에 도달했는지 확인하십시오. 이 메서드는 앱이 다른 작업으로 바쁘지 않을 때만 호출됩니다. 목표 시간에 도달했는지 확인하는 빠른 확인은 앱에 너무 많은 스트레스를주지 않아야한다고 생각합니다. - ASP.NET 웹앱에는 예약 된 이벤트를 “시뮬레이션”하는 방법이 있습니다.이 CodeProject 기사를 확인 하십시오.
- 물론 모든 .NET 앱에서 “자신 만의 롤링”을 수행 할 수도 있습니다 . 샘플 구현은 이 CodeProject 기사 를 참조하십시오.
업데이트 # 2 : 60 분마다 확인하려면 60 분마다 깨어나는 타이머를 만들고 시간이 다되면 메서드를 호출합니다.
이 같은:
using System.Timers;
const double interval60Minutes = 60 * 60 * 1000; // milliseconds to one hour
Timer checkForTime = new Timer(interval60Minutes);
checkForTime.Elapsed += new ElapsedEventHandler(checkForTime_Elapsed);
checkForTime.Enabled = true;
그런 다음 이벤트 핸들러에서 :
void checkForTime_Elapsed(object sender, ElapsedEventArgs e)
{
if (timeIsReady())
{
SendEmail();
}
}
답변
사용하기 쉽고 외부 라이브러리를 사용할 필요가없는 간단한 스케줄러를 만들었습니다. TaskScheduler는 타이머에 대한 참조를 유지하는 싱글 톤이므로 타이머가 가비지 수집되지 않고 여러 작업을 예약 할 수 있습니다. 스케줄링시이 시간이 초과되면 첫 번째 실행 (시간 및 분)을 설정할 수 있습니다.이 시간이 다음날 스케줄링 시작됩니다. 그러나 코드를 사용자 지정하는 것은 쉽습니다.
새 작업을 예약하는 것은 매우 간단합니다. 예 : 11:52에 첫 번째 작업은 15 초마다, 두 번째 예는 5 초마다입니다. 매일 실행하려면 24를 3 매개 변수로 설정하십시오.
TaskScheduler.Instance.ScheduleTask(11, 52, 0.00417,
() =>
{
Debug.WriteLine("task1: " + DateTime.Now);
//here write the code that you want to schedule
});
TaskScheduler.Instance.ScheduleTask(11, 52, 0.00139,
() =>
{
Debug.WriteLine("task2: " + DateTime.Now);
//here write the code that you want to schedule
});
내 디버그 창 :
task2: 07.06.2017 11:52:00
task1: 07.06.2017 11:52:00
task2: 07.06.2017 11:52:05
task2: 07.06.2017 11:52:10
task1: 07.06.2017 11:52:15
task2: 07.06.2017 11:52:15
task2: 07.06.2017 11:52:20
task2: 07.06.2017 11:52:25
...
프로젝트에이 클래스를 추가하기 만하면됩니다.
public class TaskScheduler
{
private static TaskScheduler _instance;
private List<Timer> timers = new List<Timer>();
private TaskScheduler() { }
public static TaskScheduler Instance => _instance ?? (_instance = new TaskScheduler());
public void ScheduleTask(int hour, int min, double intervalInHour, Action task)
{
DateTime now = DateTime.Now;
DateTime firstRun = new DateTime(now.Year, now.Month, now.Day, hour, min, 0, 0);
if (now > firstRun)
{
firstRun = firstRun.AddDays(1);
}
TimeSpan timeToGo = firstRun - now;
if (timeToGo <= TimeSpan.Zero)
{
timeToGo = TimeSpan.Zero;
}
var timer = new Timer(x =>
{
task.Invoke();
}, null, timeToGo, TimeSpan.FromHours(intervalInHour));
timers.Add(timer);
}
}
답변
이러한 기능이 필요한 애플리케이션을 구축 할 때마다 찾은 간단한 .NET 라이브러리 를 통해 항상 Windows 작업 스케줄러를 사용합니다 .
제발 비슷한 질문에 대한 내 대답을 참조 일부 샘플 코드 등을 설명합니다.
답변
다른 사람들이 말했듯이 콘솔 앱을 사용하여 예정된 시간에 실행할 수 있습니다. 다른 사람들이 말하지 않은 것은이 앱이 메인 애플리케이션에서 기다리고있는 크로스 프로세스 EventWaitHandle을 트리거 할 수 있다는 것입니다.
콘솔 앱 :
class Program
{
static void Main(string[] args)
{
EventWaitHandle handle =
new EventWaitHandle(true, EventResetMode.ManualReset, "GoodMutexName");
handle.Set();
}
}
주요 앱 :
private void Form1_Load(object sender, EventArgs e)
{
// Background thread, will die with application
ThreadPool.QueueUserWorkItem((dumby) => EmailWait());
}
private void EmailWait()
{
EventWaitHandle handle =
new EventWaitHandle(false, EventResetMode.ManualReset, "GoodMutexName");
while (true)
{
handle.WaitOne();
SendEmail();
handle.Reset();
}
}
답변
내가 알고있는 가장 간단한 방법은 Windows 작업 스케줄러를 사용하여 특정 시간에 코드를 실행하거나 응용 프로그램을 영구적으로 실행하고 특정 시간을 확인하거나 작업을 수행하는 Windows 서비스를 작성하는 것입니다. 같은.
답변
나는 이것이 오래되었다는 것을 알고 있지만 이것은 어떻습니까?
다음 실행 시간까지의 시간을 계산하는 시작시 실행할 타이머를 빌드하십시오. 런타임을 처음 호출 할 때 첫 번째 타이머를 취소하고 새로운 일일 타이머를 시작합니다. 매일 또는 원하는 주기로 변경하십시오.
답변
다음은 TPL을 사용하여이를 수행하는 방법입니다. 타이머 등을 생성 / 삭제할 필요가 없습니다.
void ScheduleSomething()
{
var runAt = DateTime.Today + TimeSpan.FromHours(16);
if (runAt <= DateTime.Now)
{
DoSomething();
}
else
{
var delay = runAt - DateTime.Now;
System.Threading.Tasks.Task.Delay(delay).ContinueWith(_ => DoSomething());
}
}
void DoSomething()
{
// do somethig
}