Кажется, все здесь думают, что внедрение Runnable - это путь, и я действительно не согласен с ними, но есть также аргументы в пользу расширения Thread, на мой взгляд, на самом деле вы его продемонстрировали в своем коде.
Если вы реализуете Runnable, то класс, который реализует Runnable, не имеет контроля над именем потока, это вызывающий код, который может установить имя потока, например:
new Thread(myRunnable,"WhateverNameiFeelLike");
но если вы расширяете Thread, тогда вы сможете управлять этим в самом классе (как в вашем примере вы называете поток ThreadB). В этом случае вы:
A) могли бы дать ему более полезное имя для целей отладки
B) заставляют использовать это имя для всех экземпляров этого класса (если вы не проигнорируете тот факт, что он является потоком и делает с ним все, как если бы он был Runnable, но мы говорим о соглашении здесь в любом случае, поэтому можем игнорировать эту возможность, которую я чувствую).
Возможно, вы даже можете возьмите трассировку стека своего создания и используйте это как имя потока. Это может показаться странным, но в зависимости от того, как структурирован ваш код, он может быть очень полезен для целей отладки.
Это может показаться небольшим, но там, где у вас очень сложное приложение с большим количеством потоков и всего внезапные вещи «остановились» (либо по причинам тупика, либо, возможно, из-за недостатка в сетевом протоколе, который был бы менее очевидным, или других бесконечных причин), а затем получить дамп стека из Java, где все потоки называются «Thread» -1 ',' Thread-2 ',' Thread-3 'не всегда очень полезен (это зависит от того, как структурированы ваши потоки и можно ли с пользой сказать, что именно по их трассировке стека - не всегда возможно, если вы используя группы из нескольких потоков, все из которых работают с одним и тем же кодом).
Сказав, что вы, конечно же, можете сделать это выше, путем создания расширения класса потока, который устанавливает его имя в трассировку стека его создания, а затем использовать его с вашими реализациями Runnable вместо стандартный класс java Thread (см. ниже), но в дополнение к трассировке стека может быть больше контекстной информации, которая была бы полезной в имени потока для отладки (ссылка на одну из многих очередей или сокетов, которые она могла бы обрабатывать, например, в этом случае вы можете предпочесть расширить Thread специально для этого случая, чтобы вы могли заставить компилятор заставить вас (или других пользователей, использующих ваши библиотеки) передавать определенную информацию (например, указанная очередь / сокет) для использования в имени).
Вот пример общего потока с трассировкой стека вызовов как его имя:
public class DebuggableThread extends Thread {
private static String getStackTrace(String name) {
Throwable t= new Throwable("DebuggableThread-"+name);
ByteArrayOutputStream os = new ByteArrayOutputStream();
PrintStream ps = new PrintStream(os);
t.printStackTrace(ps);
return os.toString();
}
public DebuggableThread(String name) {
super(getStackTrace(name));
}
public static void main(String[] args) throws Exception {
System.out.println(new Thread());
System.out.println(new DebuggableThread("MainTest"));
}
}
и вот образец выходного файла, сравнивающий два имени:
Thread[Thread-1,5,main]
Thread[java.lang.Throwable: DebuggableThread-MainTest
at DebuggableThread.getStackTrace(DebuggableThread.java:6)
at DebuggableThread.<init>(DebuggableThread.java:14)
at DebuggableThread.main(DebuggableThread.java:19)
,5,main]
Я не думаю, что есть какой-либо способ сделать это прямо в управляемом коде.
Быстрый поиск показывает этот пост от 2 лет назад. В принципе, вам нужно будет сделать какой-либо interop для вызова raw API окон.
У вас есть несколько вариантов:
ES_SYSTEM_REQUIRED
, чтобы заставить систему находиться в рабочем состоянии, сбросив таймер простоя системы. Пример SetThreadExecutionState
// Television recording is beginning. Enable away mode and prevent
// the sleep idle time-out.
SetThreadExecutionState(
ES_CONTINUOUS |
ES_SYSTEM_REQUIRED |
ES_AWAYMODE_REQUIRED);
// Wait until recording is complete...
// Clear EXECUTION_STATE flags to disable away mode and allow the system
// to idle to sleep normally.
SetThreadExecutionState(ES_CONTINUOUS);
Вы должны использовать функцию SetThreadExecutionState . Что-то вроде этого:
public partial class MyWinForm: Window
{
private uint fPreviousExecutionState;
public Window1()
{
InitializeComponent();
// Set new state to prevent system sleep
fPreviousExecutionState = NativeMethods.SetThreadExecutionState(
NativeMethods.ES_CONTINUOUS | NativeMethods.ES_SYSTEM_REQUIRED);
if (fPreviousExecutionState == 0)
{
Console.WriteLine("SetThreadExecutionState failed. Do something here...");
Close();
}
}
protected override void OnClosed(System.EventArgs e)
{
base.OnClosed(e);
// Restore previous state
if (NativeMethods.SetThreadExecutionState(fPreviousExecutionState) == 0)
{
// No way to recover; already exiting
}
}
}
internal static class NativeMethods
{
// Import SetThreadExecutionState Win32 API and necessary flags
[DllImport("kernel32.dll")]
public static extern uint SetThreadExecutionState(uint esFlags);
public const uint ES_CONTINUOUS = 0x80000000;
public const uint ES_SYSTEM_REQUIRED = 0x00000001;
}
0
означает, что метод не прошел. Из документации SetThreadExecutionState
- «Если функция завершается успешно, возвращаемое значение является предыдущим состоянием выполнения потока. Если функция не работает, возвращаемое значение равно NULL. & Quot; (Примечание. Предполагаю, что вы, вероятно, уже поняли это, но хотели опубликовать ответ для полноты и помочь любому, кто мог бы прийти и просмотреть ваш комментарий)
– pstrjds
14 June 2016 в 09:36
Вы можете использовать SetThreadExecutionState
, описанную здесь:
Поскольку это функция Win32 API, для использования его с C # вам понадобится PInvoke. Здесь описываются этапы, включая примерный метод PreventSleep
для временного отключения режима ожидания: