Итак, моя проблема здесь проста. Я разработал приложение WinForms, и оно хорошо работает на моей машине (Win7) и, фактически, на других машинах, но когда я запускаю приложение на машине Windows 10 2016 LTSB, мои фоновые потоки не работают должным образом - пока некоторые работают так, как ожидалось.
Поток приложения:
- Подождите 1 минуту (obj1 с Threading.Timer)
- Событие публикации (строковое сообщение от obj1, когда MainWindow вызывает obj1)
- Текст формы обновления (с информацией из сообщения о событии)
- Выполнение операции (фоновый поток)
- Сообщение сообщения о событии (из фонового потока в MainWindow)
- Случайный период ожидания (obj1 с Threading.Timer)
- Событие публикации (строковое сообщение от obj1)
- Форма обновления
- Подождите 1 минуту
Теперь по некоторым политикам / причинам конфиденциальности я не могу поделиться точными вещами, которые здесь работают и как структурированы классы, но вот рудиментарная структура классов:
class MainWindow
{
List<Controller> controllers = new List<Controller>();
List<ControllerDisplay> controllerDisplays = new List<ControllerDisplay>();
Queue<string> requests = new Queue<string>();
private void AppLifetimeLoopCallback(object state)
{
while (requests.Count > 0)
{
string request = requests.Dequeue();
string response = controllers[i].ProcessRequest(request);
string anotherResponse = controllerDisplays[i].ProcessResponse(response);
if (!string.NullOrWhiteSpace(anotherResponse))
{
requests.Enqueue(anotherResponse);
}
}
for (int i = 0; i < controllers.Count; i++)
{
requests.Enqueue("STATE?");
}
timer.Change(300, Threading.Timeout.Infinite);
}
}
class Controller
{
public string ProcessRequest(string request)
{
switch (request)
{
case "STATE?":
if (shouldRequest)
{
return "REQ:1234";
}
else if (isProcessing)
{
return "PRQ:1234";
}
else
{
return "IDLE";
}
break;
case "APPROVE":
shouldRequest = false;
isProcessing = true;
thread = new Threading.Thread(new ThreadStart(() =>
{
Threading.Thread.Sleep(300);
isProcessing = false;
return "RQF:1234";
})
{
IsBackground = true,
};
thread.Start();
break;
case "DENY:
shouldRequest = false;
break;
}
}
}
class ControllerDisplay
{
public string ProcessResponse(string response)
{
switch (request.Substring(0, 4))
{
case "REQ:":
thread = new Threading.Thread(new ThreadStart(() =>
{
// perform some checks
if (isValid)
{
return "APPROVE";
}
else
{
return "DENY";
}
})
{
IsBackground = true,
};
thread.Start();
break;
case "RQF:":
thread = new Threading.Thread(new ThreadStart(() =>
{
// finalize and cleanup request bits
return "APPROVE";
})
{
IsBackground = true,
};
thread.Start();
break;
case "PRQ:":
// update UI
break;
}
}
}
Теперь, во-первых, я знаю, что это кажется т o может быть некоторое несоответствие между миллисекундной задержкой в коде и описанием потока - однако обратите внимание, что есть другое Thread
в Controller
, которое переключает значение shouldRequest
в этот минутный интервал, который переключает ответные сообщения на выполнить «запрос» при запросе состояния устройства.
Во-вторых, я также зарегистрировался в UnhandledException
, а также ThreadException
событиях приложения, которые должны регистрировать любое нежелательное поведение, которое произошло.
В-третьих, обратите внимание, что в MainWindow есть Threading.Timer
(не в коде - я знаю), который обновляет пользовательский интерфейс с текущей датой и временем каждую секунду.
Теперь проблема в том, что я Заметил, что на машине Win10LTSB2016 приложение перестает выполнять фоновые операции. Некоторые из потоков, должно быть, только что умерли или что-то в этом роде, например, дата и время продолжают обновляться, как ожидалось, но один контроллер будет застрять в состоянии запроса, а другой - в состоянии завершения запроса - и сообщений об ошибках не будет / MessageBox
. Обратите внимание, что машина не go в какое-либо состояние сна или гибернации в этот период, когда потоки просто останавливаются, и еще одно примечание заключается в том, что количество сокетов памяти равно 1, а не 2 (поскольку я читал, что это может повлиять на потоки, теряющие связь с друг друга, если они разделены на разные группы процессоров и ваше приложение не написано для обработки этого).
Закрытие: обратите внимание, что когда я выполняю проверки, чтобы увидеть, должен ли я, т.е. запустить поток процесса запроса в Controller
, чтобы не выполнять один и тот же запрос снова и снова, пока не будет обнаружено изменение состояния, я делаю следующее:
lock (checkLock)
{
if (isProcessingRequest)
{
break;
}
else
{
lock (resourceLock)
{
isProcessingRequest = true;
}
}
}
thread = new Threading.Thread(new ThreadStart(() =>
{
lock (resourceLock)
{
// finalize and cleanup request bits
isProcessingRequest = false;
}
return "APPROVE";
})
{
IsBackground = true,
};
thread.Start();