我有兩個Windows .NET庫A和B。庫A有TimeBeginPeriod(1)和TimeEndPeriod(1),而庫B有TimeBeginPeriod(5)和TimeEndPeriod(5)。我最近注意到(在他們的behavor change之后),當圖書館B將進行TimeEndPeriod(5)時,圖書館A會失去TimeBeginPeriod(1)。
你能否在同一個應用程式中擁有不同的時間段而不影響另一個?我的意思是,我不介意(5)會受到(1)的影響,但關鍵是end(5)不會影響begin(1)!
在同一個應用程式中,可以有不同的時間段而不影響另一個嗎?
LibA TimeBeginPeriod(1)
.... LibB TimeBeginPeriod(5)
.... LibB TimeEndPeriod(5) < - this是否會取消TimeBeginPeriod(1)?
LibA TimeEndPeriod(1)?
[更新]
測驗代碼
using System;
using System.Runtime.InteropServices;
using System.Threading;
namespaceConsoleApp1
{
class Program {
{
static long freq;
static void Main(string[] args)?
{
QueryPerformanceFrequency(out freq)。
Console.WriteLine("Begin")。
Console.WriteLine(CalcSleep1())。
Console.WriteLine(CalcSleep1())。
TimeBeginPeriod(1)。
Console.WriteLine("TimeBeginPeriod(1)")。
Thread.Sleep(5000)。
Console.WriteLine(CalcSleep1())。
Console.WriteLine(CalcSleep1())。
Console.WriteLine(CalcSleep1())。
Console.WriteLine(CalcSleep1())。
Console.WriteLine(CalcSleep1())。
TimeBeginPeriod(15)。
Console.WriteLine("TimeBeginPeriod(15)"/span>)。
Thread.Sleep(5000)。
Console.WriteLine(CalcSleep1())。
Console.WriteLine(CalcSleep1())。
Console.WriteLine(CalcSleep1())。
Console.WriteLine(CalcSleep1())。
Console.WriteLine(CalcSleep1())。
Console.WriteLine("TimeEndPeriod(15)"/span>)。
TimeEndPeriod(15)。
Thread.Sleep(5000)。
Console.WriteLine(CalcSleep1())。
Console.WriteLine(CalcSleep1())。
Console.WriteLine(CalcSleep1())。
Console.WriteLine(CalcSleep1())。
Console.WriteLine(CalcSleep1())。
TimeEndPeriod(1)。
Console.WriteLine("TimeEndPeriod(1)")。
Console.WriteLine(CalcSleep1())。
Console.WriteLine(CalcSleep1())。
Console.WriteLine("End")。
}
private static string CalcSleep1()
{
QueryPerformanceCounter(out long ticks1) 。
Thread.Sleep(1)。
QueryPerformanceCounter(out long ticks2)。
return (new TimeSpan((long) (1000 * 10000 * (ticks2 - ticks1) / (double)req))。 ToString()。
}
[DllImport("Kernel32.dll")]
private static extern bool QueryPerformanceCounter] QueryPerformanceCounter title">QueryPerformanceCounter(out long lpPerformanceCount);
[DllImport("Kernel32.dll")]
private static extern bool QueryPerformanceFrequency(span class="hljs-keyword">out long lpFrequency);
[DllImport("winmm.dll", EntryPoint = "timeBeginPeriod", SetLastError = true)]。
public static extern uint TimeBeginPeriod(uint uMilliseconds)。
[DllImport("winmm.dll", EntryPoint = "timeEndPeriod", SetLastError = true)]
public static extern uint TimeEndPeriod(uint uMilliseconds);
[DllImport("winmm.dll", ExactSpelling = true)]
private static extern int timeGetDevCaps(ref TIMECAPS ptc。int cbtc)。
[StructLayout(LayoutKind.Sequential)]
private struct TIMECAPS
{
內部 int wPeriodMin;
internal int wPeriodMax;
}
}
輸出
Begin
00:00:00.0130730
00:00:00.0154164
TimeBeginPeriod(1)
00:00:00.0019935
00:00:00.0019148
00:00:00.0019145
00:00:00.0019203
00:00:00.0023354
TimeBeginPeriod(15)
00:00:00.0019916
00:00:00.0018920
00:00:00.0019412
00:00:00.0019411
00:00:00.0019336
TimeEndPeriod(15)
00:00:00.0019918
00:00:00.0019300
00:00:00.0019671
00:00:00.0019524
00:00:00.0019399
時間結束時間(1)
00:00:00.0152576
00:00:00.0148129
結束
似乎中間的TimeBeginPeriod(15) / TimeEndPeriod(15)并不影響TimeBeginPeriod(1)。除非這只發生在不同的組件上(還沒有測驗過)
uj5u.com熱心網友回復:
通過用一個較小的例子來編碼我的應用程式的邏輯,我能夠重現并確定一個嚴重的Windows bug。它發生在你動態加載程式集的時候。你可以下載解決方案和/或編譯的這里
更新:它同時發生在靜態/動態上。當全域定時器改變時,它有不同的行為。我的應用程式正在做以下事情,Windows不喜歡:
我的應用程式正在做以下事情。
.... LibB TimeBeginPeriod(5)。
LibA TimeBeginPeriod(1)。
.... LibB TimeEndPeriod(5) < - 這影響了TimeBeginPeriod(1)回到15ms - 當全域定時器已經到了1ms就會發生這種情況?-
LibA TimeEndPeriod(1)。
我敢打賭,這個問題會影響到許多應用程式,因為他們并不真正了解底層庫對時間周期的作用。
(將Class12 dll復制到控制臺應用程式輸出)
Class11
using System;
using System.Runtime.InteropServices;
using System.Threading;
namespace ClassLibrary1
{
public abstract class ClassAbstract
{
public abstract void StartSample(uint ms);
public abstract void EndSample(uint ms);
public abstract void PrintSample()。
}
public class Class11
{
static long freq;
public Class11()
{
QueryPerformanceFrequency(out freq)。
}
private static string CalcSleep1()
{
QueryPerformanceCounter(out long ticks1) 。
Thread.Sleep(1)。
QueryPerformanceCounter(out long ticks2)。
return (new TimeSpan((long) (1000 * 10000 * (ticks2 - ticks1) / (double)req))。 ToString()。
}
public void StartSample(uint ms)>
{
TimeBeginPeriod(ms)。
Console.WriteLine($"TimeBeginPeriod({ms})"/span>)。
PrintSample()。
}
public void EndSample(uint ms)。
{
Console.WriteLine($"TimeEndPeriod({ms})"/span>)。
TimeEndPeriod(ms)。
}
public void PrintSample()。
{
Console.WriteLine(CalcSleep1())。
Console.WriteLine(CalcSleep1())。
Console.WriteLine(CalcSleep1())。
Console.WriteLine(CalcSleep1())。
Console.WriteLine(CalcSleep1())。
}
[DllImport("Kernel32.dll")]
private static extern bool QueryPerformanceCounter] QueryPerformanceCounter title">QueryPerformanceCounter(out long lpPerformanceCount);
[DllImport("Kernel32.dll")]
private static extern bool QueryPerformanceFrequency(span class="hljs-keyword">out long lpFrequency);
[DllImport("winmm.dll", EntryPoint = "timeBeginPeriod", SetLastError = true)]。
public static extern uint TimeBeginPeriod(uint uMilliseconds)。
[DllImport("winmm.dll", EntryPoint = "timeEndPeriod", SetLastError = true)]
public static extern uint TimeEndPeriod(uint uMilliseconds) 。
}
Class12
using System;
using System.Runtime.InteropServices;
using System.Threading;
using ClassLibrary1;
namespace ClassLibrary2
{
public class Class12 : ClassAbstract
{
static long freq;
public Class12()
{
QueryPerformanceFrequency(out freq)。
}
private static string CalcSleep1()
{
QueryPerformanceCounter(out long ticks1) 。
Thread.Sleep(1)。
QueryPerformanceCounter(out long ticks2)。
return (new TimeSpan((long) (1000 * 10000 * (ticks2 - ticks1) / (double)req))。 ToString()。
}
public override void StartSample(uint ms)
{
TimeBeginPeriod(ms)。
Console.WriteLine($"TimeBeginPeriod({ms})"/span>)。
PrintSample()。
}
public override void EndSample(uint ms)
{
Console.WriteLine($"TimeEndPeriod({ms})"/span>)。
TimeEndPeriod(ms)。
}
public override void PrintSample()
{
Console.WriteLine(CalcSleep1())。
Console.WriteLine(CalcSleep1())。
Console.WriteLine(CalcSleep1())。
Console.WriteLine(CalcSleep1())。
Console.WriteLine(CalcSleep1())。
}
[DllImport("Kernel32.dll")]
private static extern bool QueryPerformanceCounter] QueryPerformanceCounter title">QueryPerformanceCounter(out long lpPerformanceCount);
[DllImport("Kernel32.dll")]
private static extern bool QueryPerformanceFrequency(span class="hljs-keyword">out long lpFrequency);
[DllImport("winmm.dll", EntryPoint = "timeBeginPeriod", SetLastError = true)]。
public static extern uint TimeBeginPeriod(uint uMilliseconds)。
[DllImport("winmm.dll", EntryPoint = "timeEndPeriod", SetLastError = true)]
public static extern uint TimeEndPeriod(uint uMilliseconds) 。
}
ConsoleApp
using System;
using System.IO;
using System.Reflection;
using ClassLibrary1;
namespace ConsoleApp1
{
class Program {
{
static Class11 class11;
static ClassAbstract class12;
static void Main(string[] args)?
{
class11 = new Class11()。
var assembly = Assembly.LoadFrom(Path.GetFullPath(@"ClassLibrary2.dll") 。)
ClassAbstract class12 = (ClassAbstract) Activator.CreateInstance(assembly.GetTypes()[0]) 。
//當系統全域時間段發生變化時,行為發生變化。
class12.StartSample(5); //這里的錯誤是我們得到1ms而不是5ms。
class11.StartSample(1)。
class12.EndSample(5)。
class11.PrintSample(); // Bug 這里我們得到15ms的周期,而不是1ms。
class11.EndSample(1)。
}
}
轉載請註明出處,本文鏈接:https://www.uj5u.com/qiye/320285.html
標籤:
