windows服务还在运行但是任务没有连续执行
windows service is still running but the task is not executed continuously
public Service1()
{
InitializeComponent();
}
protected override void OnStart(string[] args)
{
try
{
Print();
}
catch (Exception ex)
{
File.AppendAllText(@"C:\fold1\Log.txt", ex.ToString());
}
}
public static void Print()
{
//Print & Move the files after printing
DirectoryInfo sourceinfo = new DirectoryInfo(@"C:\fold");
DirectoryInfo target = new DirectoryInfo(@"C:\fold1");
foreach (FileInfo fi in sourceinfo.GetFiles())
{
if (fi.Length != 0)
{
System.Diagnostics.Process process = new System.Diagnostics.Process();
process.StartInfo.CreateNoWindow = true;
process.StartInfo.Verb = "print";
process.StartInfo.FileName = fi.FullName;
process.StartInfo.UseShellExecute = true;
process.StartInfo.WindowStyle = System.Diagnostics.ProcessWindowStyle.Hidden;
process.Start();
if (!process.WaitForExit(10000))
process.Kill();
}
MoveFile(fi.FullName);
}
}
public static void MoveFile(string Filename)
{
string SourcePath = @"C:\fold";
string targetpath = @"C:\fold1";
if (!Directory.Exists(targetpath))
{
Directory.CreateDirectory(targetpath);
}
string[] sourceFiles = Directory.GetFiles(SourcePath);
foreach (string sourcefile in sourceFiles)
{
string mfilename = Path.GetFullPath(sourcefile);
string mname = Path.GetFileName(sourcefile);
if (mfilename == Filename)
{
string distnition = Path.Combine(targetpath, mname);
File.Move(mfilename, distnition);
}
}
}
protected override void OnStop()
{ try
{
//Move the files after printing
DirectoryInfo sourceinfo = new DirectoryInfo(@"C:\fold");
DirectoryInfo target = new DirectoryInfo(@"C:\fold1");
foreach (FileInfo fi in sourceinfo.GetFiles())
{
// File.AppendAllText(@"C:\fold1\stop.txt", "Stop method");
MoveFile(fi.FullName);
}
}
catch (Exception ex)
{
File.AppendAllText(@"C:\fold1\Log.txt", ex.ToString());
}
}
我创建了一个服务,可以静默打印给定目录中的文件,然后将它们移动到另一个目录,当我第一次尝试启动它时它工作正常,但它不会 运行 持续,我想要它打印并移动复制到该目录中的任何文件,那么我该怎么办?
请注意,我仍然是 c# 的初学者,如果您的解释太复杂,我不太理解,谢谢
问题是,您的 OnStart()
方法已经完成了具体工作,而 从未 returns。但是服务管理器的设计是,它最多等待 60 秒直到 OnStart()
方法 returns,否则进程将被终止。
因此,与其直接在 OnStart()
方法中调用您的代码,不如实例化一个新任务或线程来完成工作并立即退出 OnStart()
方法。在 OnStop()
方法中,您必须通知并行 运行 代码停止(例如,通过使用 CancellationToken
)并等待它完成然后退出。
示例
public partial class ServiceExample : ServiceBase
{
public ServiceExample()
{
InitializeComponent();
}
private Task Runner;
private CancellationTokenSource Cts;
protected override void OnStart(string[] args)
{
if (Cts != null) // Could also simply return
throw new InvalidOperationException("Service is already running!");
Cts = new CancellationTokenSource();
Runner = DoSomething(Cts.Token);
}
private async Task DoSomething(CancellationToken cancellationToken)
{
// Immediately return to caller to avoid "hanging" OnStart()
await Task.Yield();
// Regulary check if OnStop() is waiting for us
while (!cancellationToken.IsCancellationRequested)
{
// Call your method that should do something.
// If it runs longer and can be intercepted,
// forward the CancellationToken to it.
await Worker(cancellationToken);
}
}
protected override void OnStop()
{
if (Cts == null) // Could also simply return
throw new InvalidOperationException("Service already being stopped!");
Cts.Cancel();
Runner.Wait();
}
private async Task Worker(CancellationToken cancellationToken)
{
Trace.WriteLine($"{DateTime.UtcNow}: Do some heavy work!");
await Task.Delay(TimeSpan.FromSeconds(1));
if (cancellationToken.IsCancellationRequested)
return;
await Task.Delay(TimeSpan.FromSeconds(1));
}
}
public Service1()
{
InitializeComponent();
}
protected override void OnStart(string[] args)
{
try
{
Print();
}
catch (Exception ex)
{
File.AppendAllText(@"C:\fold1\Log.txt", ex.ToString());
}
}
public static void Print()
{
//Print & Move the files after printing
DirectoryInfo sourceinfo = new DirectoryInfo(@"C:\fold");
DirectoryInfo target = new DirectoryInfo(@"C:\fold1");
foreach (FileInfo fi in sourceinfo.GetFiles())
{
if (fi.Length != 0)
{
System.Diagnostics.Process process = new System.Diagnostics.Process();
process.StartInfo.CreateNoWindow = true;
process.StartInfo.Verb = "print";
process.StartInfo.FileName = fi.FullName;
process.StartInfo.UseShellExecute = true;
process.StartInfo.WindowStyle = System.Diagnostics.ProcessWindowStyle.Hidden;
process.Start();
if (!process.WaitForExit(10000))
process.Kill();
}
MoveFile(fi.FullName);
}
}
public static void MoveFile(string Filename)
{
string SourcePath = @"C:\fold";
string targetpath = @"C:\fold1";
if (!Directory.Exists(targetpath))
{
Directory.CreateDirectory(targetpath);
}
string[] sourceFiles = Directory.GetFiles(SourcePath);
foreach (string sourcefile in sourceFiles)
{
string mfilename = Path.GetFullPath(sourcefile);
string mname = Path.GetFileName(sourcefile);
if (mfilename == Filename)
{
string distnition = Path.Combine(targetpath, mname);
File.Move(mfilename, distnition);
}
}
}
protected override void OnStop()
{ try
{
//Move the files after printing
DirectoryInfo sourceinfo = new DirectoryInfo(@"C:\fold");
DirectoryInfo target = new DirectoryInfo(@"C:\fold1");
foreach (FileInfo fi in sourceinfo.GetFiles())
{
// File.AppendAllText(@"C:\fold1\stop.txt", "Stop method");
MoveFile(fi.FullName);
}
}
catch (Exception ex)
{
File.AppendAllText(@"C:\fold1\Log.txt", ex.ToString());
}
}
我创建了一个服务,可以静默打印给定目录中的文件,然后将它们移动到另一个目录,当我第一次尝试启动它时它工作正常,但它不会 运行 持续,我想要它打印并移动复制到该目录中的任何文件,那么我该怎么办? 请注意,我仍然是 c# 的初学者,如果您的解释太复杂,我不太理解,谢谢
问题是,您的 OnStart()
方法已经完成了具体工作,而 从未 returns。但是服务管理器的设计是,它最多等待 60 秒直到 OnStart()
方法 returns,否则进程将被终止。
因此,与其直接在 OnStart()
方法中调用您的代码,不如实例化一个新任务或线程来完成工作并立即退出 OnStart()
方法。在 OnStop()
方法中,您必须通知并行 运行 代码停止(例如,通过使用 CancellationToken
)并等待它完成然后退出。
示例
public partial class ServiceExample : ServiceBase
{
public ServiceExample()
{
InitializeComponent();
}
private Task Runner;
private CancellationTokenSource Cts;
protected override void OnStart(string[] args)
{
if (Cts != null) // Could also simply return
throw new InvalidOperationException("Service is already running!");
Cts = new CancellationTokenSource();
Runner = DoSomething(Cts.Token);
}
private async Task DoSomething(CancellationToken cancellationToken)
{
// Immediately return to caller to avoid "hanging" OnStart()
await Task.Yield();
// Regulary check if OnStop() is waiting for us
while (!cancellationToken.IsCancellationRequested)
{
// Call your method that should do something.
// If it runs longer and can be intercepted,
// forward the CancellationToken to it.
await Worker(cancellationToken);
}
}
protected override void OnStop()
{
if (Cts == null) // Could also simply return
throw new InvalidOperationException("Service already being stopped!");
Cts.Cancel();
Runner.Wait();
}
private async Task Worker(CancellationToken cancellationToken)
{
Trace.WriteLine($"{DateTime.UtcNow}: Do some heavy work!");
await Task.Delay(TimeSpan.FromSeconds(1));
if (cancellationToken.IsCancellationRequested)
return;
await Task.Delay(TimeSpan.FromSeconds(1));
}
}