Итак, это просто объяснить, но я искал и не могу найти никого с той же проблемой. Моя проблема возникла в долгосрочной периодической задаче, которая выполнялась чаще, чем я хотел. Кажется, каждый Task.Delay() я создаю и ожидаю возвращения примерно в 65% от задержки, указанной в ms.
Проблема сводилась к следующей строке кода, возвращающейся примерно в 640-660 мс (по сравнению с визуальной студией. Я установил точку останова на этой строке кода и следующую за ней, и она сказала, что прошло)
await Task.Delay(1000);
На двух других машинах базовая база IDENTICAL работает нормально. Не только это простое утверждение выше, но и периодические задачи. Есть ли настройка где-нибудь, что повлияет на Task.Delay(int millisecondsDelay)? Тип тика, тактовая частота, что угодно, системные часы??? Я в недоумении...
EDIT:
В нижеприведенном фрагменте EtMilliseconds находится где-то от 130-140 мс, что примерно равно ок. 65% ожидаемой продолжительности, указанной выше. Никогда ничего за пределами этого (кроме первого раза во время(), которое не имеет значения).
Long EtMilliseconds;
Stopwatch etWatch = new Stopwatch();
etWatch.Restart();
while (true)
{
EtMilliseconds = etWatch.ElapsedMilliseconds;
taskDelay = Task.Delay(200);
etWatch.Restart();
await taskDelay;
}
ИЗМЕНИТЬ 2:
Следующий код заставляет EtMilliseconds еще раз 131 мс или около того. Использование Thread.Sleep кажется неэффективным...
public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
}
private void button_Click(object sender, RoutedEventArgs e)
{
long EtMilliseconds;
Stopwatch etWatch = new Stopwatch();
etWatch.Restart();
while (true)
{
EtMilliseconds = etWatch.ElapsedMilliseconds;
label.Content = EtMilliseconds.ToString();
etWatch.Restart();
Thread.Sleep(200);
}
}
}
Этот фрагмент тот же, но использует Task.Delay(200). Этот флажок правильно обновляет метку графического интерфейса (Thread.Sleep не работает), и он равен 131 или 140 мс. Всегда...
public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
}
private async void button_Click(object sender, RoutedEventArgs e)
{
Task taskDelay;
long EtMilliseconds;
Stopwatch etWatch = new Stopwatch();
etWatch.Restart();
while (true)
{
EtMilliseconds = etWatch.ElapsedMilliseconds;
label.Content = EtMilliseconds.ToString();
taskDelay = Task.Delay(200);
etWatch.Restart();
await taskDelay;
}
}
}
ИЗМЕНИТЬ 3:
Вместо использования DispatcherTimer я все еще получаю примерно 130 мс от своего секундомера .ElapsedMilliseconds... НО здесь странная вещь. Если я также обновляю отображение DateTime.Now(), они увеличиваются примерно на 200 мс (или чуть больше), что я и ожидал. Что за?!?!
public partial class MainWindow : Window
{
public long etMilliseconds;
public Stopwatch etWatch;
public MainWindow()
{
InitializeComponent();
this.DataContext = this;
}
// System.Windows.Threading.DispatcherTimer.Tick handler
//
// Updates the current seconds display and calls
// InvalidateRequerySuggested on the CommandManager to force
// the Command to raise the CanExecuteChanged event.
private void dispatcherTimer_Tick(object sender, EventArgs e)
{
// Updating the Label which displays the current second
tBoxCurrTime.Text += DateTime.Now.ToString("yyyy_MMM_dd-hh:mm:ss.fff_tt") + "\n";
tBoxMilliSecElapsed.Text += etWatch.ElapsedMilliseconds + "\n";
etWatch.Restart();
// Forcing the CommandManager to raise the RequerySuggested event
CommandManager.InvalidateRequerySuggested();
}
private void button_Click(object sender, RoutedEventArgs e)
{
etWatch = new Stopwatch();
// DispatcherTimer setup
DispatcherTimer dispatcherTimer = new System.Windows.Threading.DispatcherTimer();
dispatcherTimer.Tick += new EventHandler(dispatcherTimer_Tick);
dispatcherTimer.Interval = new TimeSpan(0, 0, 0, 0, 200);
dispatcherTimer.Start();
etWatch.Restart();
}
}