C#性能计数器冻结用户界面
好的,我的程序中有一个计算CPU使用率的performancecounter。它工作得很好,没有bug等等。。。但是每当performancecounter加载时,我的UI就会冻结 我在backgroundworker中加载performancecounter,所以我不知道为什么它会冻结UI 有什么想法吗?如果是,谢谢 代码C#性能计数器冻结用户界面,c#,backgroundworker,performancecounter,C#,Backgroundworker,Performancecounter,好的,我的程序中有一个计算CPU使用率的performancecounter。它工作得很好,没有bug等等。。。但是每当performancecounter加载时,我的UI就会冻结 我在backgroundworker中加载performancecounter,所以我不知道为什么它会冻结UI 有什么想法吗?如果是,谢谢 代码 private void backgroundWorker1_DoWork(object sender, System.ComponentModel.DoWorkEvent
private void backgroundWorker1_DoWork(object sender, System.ComponentModel.DoWorkEventArgs e)
{
try
{
SetPerformanceCounters();
timerUpdateGUIControls.Start();
}
catch (Exception ex)
{
Console.WriteLine(ex);
}
}
private void SetPerformanceCounters()
{
performanceCounterCPU.CounterName = "% Processor Time";
performanceCounterCPU.CategoryName = "Processor";
performanceCounterCPU.InstanceName = "_Total";
performanceCounterRAM.CounterName = "% Committed Bytes In Use";
performanceCounterRAM.CategoryName = "Memory";
}
private void timerUpdateGUIControls_Tick(object sender, EventArgs e)
{
try
{
SystemStatusprogressbarCPU.Value = (int)(performanceCounterCPU.NextValue());
SystemStatuslabelCPU.Text = "CPU: " + SystemStatusprogressbarCPU.Value.ToString(CultureInfo.InvariantCulture) + "%";
var phav = PerformanceInfo.GetPhysicalAvailableMemoryInMiB();
var tot = PerformanceInfo.GetTotalMemoryInMiB();
var percentFree = ((decimal)phav / tot) * 100;
var percentOccupied = 100 - percentFree;
SystemStatuslabelRAM.Text = "RAM: " + (percentOccupied.ToString(CultureInfo.InvariantCulture) + "%").Remove(2, 28);
SystemStatusprogressbarRAM.Value = Convert.ToInt32((percentOccupied));
}
catch (Exception ex)
{
Console.WriteLine(ex);
}
}
获取RAM值填充的类:
public static class PerformanceInfo
{
[DllImport("psapi.dll", SetLastError = true)]
[return: MarshalAs(UnmanagedType.Bool)]
public static extern bool GetPerformanceInfo([Out] out PerformanceInformation PerformanceInformation,
[In] int Size);
[StructLayout(LayoutKind.Sequential)]
public struct PerformanceInformation
{
public int Size;
public IntPtr CommitTotal;
public IntPtr CommitLimit;
public IntPtr CommitPeak;
public IntPtr PhysicalTotal;
public IntPtr PhysicalAvailable;
public IntPtr SystemCache;
public IntPtr KernelTotal;
public IntPtr KernelPaged;
public IntPtr KernelNonPaged;
public IntPtr PageSize;
public int HandlesCount;
public int ProcessCount;
public int ThreadCount;
}
public static Int64 GetPhysicalAvailableMemoryInMiB()
{
var pi = new PerformanceInformation();
if (GetPerformanceInfo(out pi, Marshal.SizeOf(pi)))
{
return Convert.ToInt64((pi.PhysicalAvailable.ToInt64() * pi.PageSize.ToInt64() / 1048576));
}
return -1;
}
public static Int64 GetTotalMemoryInMiB()
{
var pi = new PerformanceInformation();
if (GetPerformanceInfo(out pi, Marshal.SizeOf(pi)))
{
return Convert.ToInt64((pi.PhysicalTotal.ToInt64() * pi.PageSize.ToInt64() / 1048576));
}
return -1;
}
}
您可以在backgroundworker的DoWork中创建性能计数器。但这只是创作,而不是实际工作。您应该将内容从
timerUpdateGUIControls\u Tick
移动到backgroundWorker1\u DoWork
struct SystemStatus
{
public int CpuLoad;
public decimal OccupiedPercentage;
}
private void SetPerformanceCounters()
{
performanceCounterCPU.CounterName = "% Processor Time";
performanceCounterCPU.CategoryName = "Processor";
performanceCounterCPU.InstanceName = "_Total";
performanceCounterRAM.CounterName = "% Committed Bytes In Use";
performanceCounterRAM.CategoryName = "Memory";
}
private void backgroundWorker1_DoWork(object sender, System.ComponentModel.DoWorkEventArgs e)
{
try
{
SetPerformanceCounters();
while (!backgroundWorker1.CancellationPending)
{
SystemStatus status = new SystemStatus();
status.CpuLoad = (int)(performanceCounterCPU.NextValue())
var phav = PerformanceInfo.GetPhysicalAvailableMemoryInMiB();
var tot = PerformanceInfo.GetTotalMemoryInMiB();
var percentFree = ((decimal)phav / tot) * 100;
status.OccupiedPercentage = 100 - percentFree;
backgroundWorker1.ReportProgress(0, status);
Thread.Sleep(500); //set update frequency to 500ms
}
}
catch (Exception ex)
{
Console.WriteLine(ex);
}
}
private void backgroundWorker1_ProgressChanged(object sender, ProgressChangedEventArgs e)
{
SystemStatus status = e.UserState as SystemStatus;
SystemStatusprogressbarCPU.Value = status.CpuLoad;
SystemStatuslabelCPU.Text = "CPU: " + Sstatus.CpuLoad.ToString(CultureInfo.InvariantCulture) + "%";
SystemStatuslabelRAM.Text = "RAM: " + (status.OccupiedPercentage.ToString(CultureInfo.InvariantCulture) + "%").Remove(2, 28);
SystemStatusprogressbarRAM.Value = Convert.ToInt32(status.OccupiedPercentage);
}
不要忘记将ProgressChanged函数添加到backgroundworker1:
backgroundWorker1.ProgressChanged += new ProgressChangedEventHandler(backgroundWorker1_ProgressChanged);
@哦,是的,对不起。添加了代码。但是如果在BackgroundWorker中,我如何每500毫秒更新一次
timerUpdateGUIControls\u Tick
中的内容?Okai,我正在尝试用以下内容更新标签和progressbar交叉线程:Invoke((MethodInvoker)delegate{/*the code*/})代码>但它仍然冻结用户界面。(假设它现在变为白色:o)。使用BackgroundWorker提供的ReportProgress更新了代码。