C# 服务不是';t正在运行Task.run
我已经编写了一个windows服务。 下面是类中定义的全局变量:C# 服务不是';t正在运行Task.run,c#,multithreading,windows-services,C#,Multithreading,Windows Services,我已经编写了一个windows服务。 下面是类中定义的全局变量: private static TimeSpan pollingInterval; private static Thread regenerationThread; private static ManualResetEvent quitThreadEvent; private static ConcurrentQueue<KeyValuePair<string, string>> queue = new
private static TimeSpan pollingInterval;
private static Thread regenerationThread;
private static ManualResetEvent quitThreadEvent;
private static ConcurrentQueue<KeyValuePair<string, string>> queue = new ConcurrentQueue<KeyValuePair<string, string>>();
下面是上面提到的doStart方法:
internal static void doStart()
{
queue.Enqueue(new KeyValuePair<string, string>("user1", "password1"));
queue.Enqueue(new KeyValuePair<string, string>("user2", "password2"));
queue.Enqueue(new KeyValuePair<string, string>("user3", "password3"));
while (!quitThreadEvent.WaitOne(pollingInterval))
{
// tempList isn't empty, I checked it putting logs here.
if (tempList.Length != 0)
{
var temp = new KeyValuePair<string, string>();
if (queue.TryDequeue(out temp))
{
string username = temp.Key;
string password = temp.Value;
// Method comes till here but doesn't execute the statement below and directly reach to end WriteToFile method.
Task.Run(async () =>
{
await tempFunc(username, password);
queue.Enqueue(new KeyValuePair<string, string>(username, password));
});
}
}
WriteToFile("End of Method");
}
}
内部静态void doStart()
{
排队(新的KeyValuePair(“user1”、“password1”);
排队(新的KeyValuePair(“user2”、“password2”);
排队(新的KeyValuePair(“user3”、“password3”);
而(!quitThreadEvent.WaitOne(pollingInterval))
{
//圣殿骑士不是空的,我把日志放在这里检查过了。
if(templast.Length!=0)
{
var temp=新的KeyValuePair();
if(queue.TryDequeue(out temp))
{
字符串用户名=临时密钥;
字符串密码=临时值;
//方法一直到这里,但不执行下面的语句并直接到达end WriteToFile方法。
Task.Run(异步()=>
{
等待tempFunc(用户名、密码);
排队(新的KeyValuePair(用户名、密码));
});
}
}
WriteToFile(“方法结束”);
}
}
我不确定为什么
任务.Run
不起作用。我已经放置了日志,但它没有显示任何错误。我尝试将日志放入任务中。运行,但它不显示这些日志。是我启动线程然后调用任务的原因。在线程内运行
?我已经重写了您的代码,只使用异步/等待模式
private static TimeSpan pollingInterval;
private static Task regenerationTask;
private static CancellationTokenSource quitThreadEvent;
private static ConcurrentQueue<KeyValuePair<string, string>> queue = new ConcurrentQueue<KeyValuePair<string, string>>();
internal static void Start()
{
pollingInterval = TimeSpan.FromSeconds(100);
quitThreadEvent = new CancellationTokenSource();
regenerationTask = ExecuteAsync( quitThreadEvent.Token );
}
尽管您的代码并不像人们所说的那样是一种很好的实现方式,但是您的代码也应该可以工作,除非您的代码在其他地方有问题。我在当地试过,效果不错。但是“while(!quitThreadEvent.WaitOne(pollingInterval))”会阻止内部代码执行“pollingInterval”(100秒),除非您在其他地方设置了quitThreadEvent。确保你的程序不会在100秒前结束。如果它提前结束,您可能看不到执行结果。
这是一个工作版本代码:
internal static void Start()
{
pollingInterval = TimeSpan.FromSeconds(1);
quitThreadEvent = new ManualResetEvent(false);
regenerationThread = new Thread(doStart);
regenerationThread.Start();
}
internal static void doStart()
{
queue.Enqueue(new KeyValuePair<string, string>("user1", "password1"));
queue.Enqueue(new KeyValuePair<string, string>("user2", "password2"));
queue.Enqueue(new KeyValuePair<string, string>("user3", "password3"));
while (!quitThreadEvent.WaitOne(pollingInterval))
{
// tempList isn't empty, I checked it putting logs here.
if (true)
{
var temp = new KeyValuePair<string, string>();
if (queue.TryDequeue(out temp))
{
string username = temp.Key;
string password = temp.Value;
// Method comes till here but doesn't execute the statement below and directly reach to end WriteToFile method.
Task.Run(async () =>
{
await tempFunc(username, password);
queue.Enqueue(new KeyValuePair<string, string>(username, password));
});
}
Console.WriteLine("End of the method.");
break;
}
}
}
internal static async Task tempFunc(string userName, string pwd)
{
Console.WriteLine($"UserName = {userName}, Pwd = {pwd}");
await Task.Delay(1000);
}
static void Main(string[] args)
{
Start();
Thread.Sleep(5000);
}
内部静态无效开始()
{
pollingInterval=从秒开始的时间跨度(1);
quitThreadEvent=新的ManualResetEvent(错误);
再生线程=新线程(doStart);
reseactionThread.Start();
}
内部静态void doStart()
{
排队(新的KeyValuePair(“user1”、“password1”);
排队(新的KeyValuePair(“user2”、“password2”);
排队(新的KeyValuePair(“user3”、“password3”);
而(!quitThreadEvent.WaitOne(pollingInterval))
{
//圣殿骑士不是空的,我把日志放在这里检查过了。
如果(真)
{
var temp=新的KeyValuePair();
if(queue.TryDequeue(out temp))
{
字符串用户名=临时密钥;
字符串密码=临时值;
//方法一直到这里,但不执行下面的语句并直接到达end WriteToFile方法。
Task.Run(异步()=>
{
等待tempFunc(用户名、密码);
排队(新的KeyValuePair(用户名、密码));
});
}
WriteLine(“方法结束”);
打破
}
}
}
内部静态异步任务tempFunc(字符串用户名,字符串pwd)
{
WriteLine($“UserName={UserName},Pwd={Pwd}”);
等待任务。延迟(1000);
}
静态void Main(字符串[]参数)
{
Start();
睡眠(5000);
}
`为什么不使用Task.Run()
而不是线程?不需要任务。在这个上下文中运行我没有理解。您是否建议改为recreationthread=newthread(doStart)代码>和再生线程.Start()代码>语句。使用Task.Run()
启动方法doStart
@ClintyourDoStart()
可以是一个异步任务DoTask()
@SirRufo,实际上我希望tempFunc
方法被异步调用多次,所以我认为Task.Run
是一种正确的方法吗?或者我遗漏了什么?等待任务。延迟(pollingInterval,cancellationToken)。配置等待(false)代码>这到底是做什么的?假设我有一个async
方法,我必须把wait
放在其中,但我不想等待其他任何东西。因此,如果我在上面的语句中把pollingInterval设置为0,那么它能完成这个任务吗?试图理解我提到的语句。实际上谈论tempFunc
,如果我在tempFunc
中有一堆语句,我只是不想在任何地方等待并异步执行该方法,使等待任务。Dealy(0)
会为我做这件事吗?@sporty_1993任务。延迟(…)
将等待给定的延迟,但在cacellationToken处于取消状态时引发异常。这有点像你的活动ConfigureAwait(false)
将导致任务无法捕获当前同步上下文,并将在工作线程上继续执行。task.Delay(0)。ConfigureAwait(false)
与您不写任何内容时相同。如果要继续工作线程,则必须等待Task.Delay(1).ConfigureAwait(false)在您提到的代码中,代码执行将在wait Task.Deay()
处停止,等待pollingInterval
,然后继续执行,对吗?但是这里await tempFunc(用户名、密码)
之后,它将在主线程中继续运行,同时运行tempFunc
我正在设置quitThreadEvent,只有当我停止服务时。但是仍然没有调用该方法,我不知道为什么。
internal static async Task ExecuteAsync(CancellationToken cancellationToken)
{
queue.Enqueue(new KeyValuePair<string, string>("user1", "password1"));
queue.Enqueue(new KeyValuePair<string, string>("user2", "password2"));
queue.Enqueue(new KeyValuePair<string, string>("user3", "password3"));
while ( true )
{
await Task.Delay( pollingInterval, cancellationToken ).ConfigureAwait( false );
// tempList isn't empty, I checked it putting logs here.
if (tempList.Length != 0)
{
var temp = new KeyValuePair<string, string>();
if (queue.TryDequeue(out temp))
{
string username = temp.Key;
string password = temp.Value;
// fire and forget task - we do not want to await
// so we do not need to store the task instance
_ = WorkWithAsync(username, password);
}
}
WriteToFile("End of Method");
}
}
private static async Task WorkWithAsync( string username, string password )
{
await tempfunc( username, password ).ConfigureAwait( false );
queue.Enqueue(new KeyValuePair<string, string>(username, password));
}
internal static void Stop()
{
quitThreadEvent.Cancel();
regenerationTask.Wait();
}
internal static async Task StopAsync()
{
quitThreadEvent.Cancel();
await regenerationTask;
}
internal static void Start()
{
pollingInterval = TimeSpan.FromSeconds(1);
quitThreadEvent = new ManualResetEvent(false);
regenerationThread = new Thread(doStart);
regenerationThread.Start();
}
internal static void doStart()
{
queue.Enqueue(new KeyValuePair<string, string>("user1", "password1"));
queue.Enqueue(new KeyValuePair<string, string>("user2", "password2"));
queue.Enqueue(new KeyValuePair<string, string>("user3", "password3"));
while (!quitThreadEvent.WaitOne(pollingInterval))
{
// tempList isn't empty, I checked it putting logs here.
if (true)
{
var temp = new KeyValuePair<string, string>();
if (queue.TryDequeue(out temp))
{
string username = temp.Key;
string password = temp.Value;
// Method comes till here but doesn't execute the statement below and directly reach to end WriteToFile method.
Task.Run(async () =>
{
await tempFunc(username, password);
queue.Enqueue(new KeyValuePair<string, string>(username, password));
});
}
Console.WriteLine("End of the method.");
break;
}
}
}
internal static async Task tempFunc(string userName, string pwd)
{
Console.WriteLine($"UserName = {userName}, Pwd = {pwd}");
await Task.Delay(1000);
}
static void Main(string[] args)
{
Start();
Thread.Sleep(5000);
}