我有以下代码 - 我有一个在控制台应用程序的后台永久运行的线程。如果在该任务中抛出异常,我需要传播到主线程。我怎么能这样做?
private void StartTask()
{
Task.Run(() =>
{
while (_subStatus)
{
// do work here
// an exception might be thrown
}
});
}
编辑: 我不够清楚。该任务旨在运行应用程序的生命周期。它不需要返回结果。我确实想知道然后在任务中抛出异常。它看起来像这样:
static void Main(string[] args)
{
//setup
StartTask()
// continue to do other work in the main thread
while (true)
{
// main thread work
}
}
EDIT2:使用以下代码我至少可以记录错误
private async Task StartTask()
{
try{
await Task.Run(() =>
{
while (_subStatus)
{
// do work here
// an exception might be thrown
}
});
}catch(exception e)
{ //log exception here, still not on the main thread though }
}
最终编辑: 从底部的答案:https://github.com/Topshelf/Topshelf/issues/245 对于长时间运行的任务(线程),我应该执行以下操作:
new Thread(() => {
// your exception here will stop the service or take down the app
}).Start();
不是这个:
Task.Run(() => {
// your thrown exception here won't stop the service
});
答案 0 :(得分:-1)
这使得worker和main两个线程都可以被监视,如果一个抛出异常,app就会退出,或者你可以抛出异常
工作线程有一个监视器线程,它可以处理异常并在不退出的情况下做一些合理的事情,或者在这种情况下它会重新抛出并将其发送回主线程,这将退出应用程序。
static void Main(string[] args)
{
var tokenSource = new CancellationTokenSource();
var token = tokenSource.Token;
var worker = Task.Run(async () =>
{
try
{
var task = Task.Run(() => throw new Exception("hi"));
await task;
}
catch (Exception e)
{
Console.WriteLine("Async...");
throw;
}
}, token);
var main = Task.Run(() =>
{
while (!token.IsCancellationRequested)
{
Thread.Sleep(1);
}
}, token);
var tasks = new[] { worker, main };
var index = Task.WaitAny(tasks);
var taskThatStopped = tasks[index];
if (taskThatStopped.IsFaulted)
{
Console.WriteLine("Task quit because of a fault");
Console.WriteLine(taskThatStopped.Exception.InnerException.Message);
}
tokenSource.Cancel();
try
{
Task.WaitAll(tasks);
}
catch (Exception e)
{
}
}