Я пытаюсь запустить приложение консоли через определенное время (это связано с тем, что я тестирую, начнет ли приложение после сбоя. Следующее this учебник)Приложение не будет разбиваться по назначению, пока в другом потоке
Что я за это этот кусок кода:
static class WebSocket
{
static int Main(string[] args)
{
Recovery.RegisterForAutostart();
Recovery.RegisterForRestart();
Test.Run();
// some more code
}
}
public static class Recovery
{
[Flags]
public enum RestartRestrictions
{
None = 0,
NotOnCrash = 1,
NotOnHang = 2,
NotOnPatch = 4,
NotOnReboot = 8
}
public delegate int RecoveryDelegate(RecoveryData parameter);
public static class ArrImports
{
[DllImport("kernel32.dll")]
public static extern void ApplicationRecoveryFinished(
bool success);
[DllImport("kernel32.dll")]
public static extern int ApplicationRecoveryInProgress(
out bool canceled);
[DllImport("kernel32.dll")]
public static extern int GetApplicationRecoveryCallback(
IntPtr processHandle,
out RecoveryDelegate recoveryCallback,
out RecoveryData parameter,
out uint pingInterval,
out uint flags);
[DllImport("KERNEL32.dll", CharSet = CharSet.Unicode, SetLastError = true)]
public static extern int GetApplicationRestartSettings(
IntPtr process,
IntPtr commandLine,
ref uint size,
out uint flags);
[DllImport("kernel32.dll")]
public static extern int RegisterApplicationRecoveryCallback(
RecoveryDelegate recoveryCallback,
RecoveryData parameter,
uint pingInterval,
uint flags);
[DllImport("kernel32.dll")]
public static extern int RegisterApplicationRestart(
[MarshalAs(UnmanagedType.BStr)] string commandLineArgs,
int flags);
[DllImport("kernel32.dll")]
public static extern int UnregisterApplicationRecoveryCallback();
[DllImport("kernel32.dll")]
public static extern int UnregisterApplicationRestart();
}
public class RecoveryData
{
string currentUser;
public RecoveryData(string who)
{
currentUser = who;
}
public string CurrentUser
{
get { return currentUser; }
}
}
// Restart after crash
public static void RegisterForRestart()
{
// Register for automatic restart if the application was terminated for any reason.
ArrImports.RegisterApplicationRestart("/restart",
(int)RestartRestrictions.None);
}
// Start app when PC starts
public static void RegisterForAutostart()
{
#if (!DEBUG)
RegistryKey key = Registry.CurrentUser.OpenSubKey("SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Run", true);
key.SetValue("websocket", @"c:\websocket\run.bat");
#endif
}
public static class Test
{
public static void Run()
{
crash();
}
static void crash()
{
double crashAfter = 1.5 * 60; // seconds
int secondsPassed = 0;
int waitSeconds = 1;
Console.WriteLine("\nCrash test startet, crash will occour in " + crashAfter + " seconds");
Timer timer = new Timer(
delegate (object seconds) {
secondsPassed += int.Parse(seconds.ToString());
if (secondsPassed > crashAfter)
{
Console.WriteLine("Crashing");
Environment.FailFast("Test - intentional crash."); // Error happens here
}
else
{
double timeUntilCrash = (crashAfter - secondsPassed);
Console.WriteLine("Time until crash = " + timeUntilCrash + " seconds");
}
},
waitSeconds,
TimeSpan.FromSeconds(waitSeconds),
TimeSpan.FromSeconds(waitSeconds));
}
}
Когда пришло время аварии я получаю сообщение:
не может оценить выражение, потому что нить останавливается в точке , где сбор мусора невозможно, возможно, потому, что код оптимизирован.
Флажок для оптимизации кода не установлен.
Я считаю, что это не в основном потоке, если это так, как я могу вернуться в основной поток. А если нет, что может быть причиной?
Это звучит как сообщение отладчика из-за того, что вы пытаетесь просмотреть какую-либо переменную во время закрытия программы. Я подозреваю, что ваша настоящая проблема заключается в том, что таймер собирает мусор. Попробуйте назначить его статическому полю, а не удерживать его в локальной переменной стека. –
@MatthewWatson: Это может быть глупый вопрос, но разве он не является статичным, следовательно, «static void crash()» или вы говорите о том, что статический таймер «статичный» как статический таймер таймера =? –
Как отметил @MatthewWatson - ваш объект Timer назначается локальной переменной _timer_. Когда _timer_ выходит из области действия при выходе из метода _crash_, ссылки на объект Timer отсутствуют, и он доступен для сбора мусора. Переменная _timer_ должна оставаться в области при выходе из _crash_, поэтому сделать это поле включенного класса (возможно, статического) будет решением. – PaulF