. InteropBitmap'in WriteableBitmap'ten daha hızlı olacağını düşündüm: Bellek bölümünden kendini güncelleme yeteneği var.birlikte GDI + ile WPF'ın InteropBitmap: Ben <strong>System.Drawing.Graphics</strong> ve WPF'ın <strong>InteropBitmap</strong> kullanarak bazı rasgele dikdörtgenler her 30 msn kılan küçük wpf testi uygulaması oluşturduk yüksek cpu kullanımı
Uygulamayı çalıştırırken (ekran boyutu 1600 * 1200), cpu kullanımı, çift çekirdekli bir 3GHz ile yalnızca yaklaşık 2-10% olur. Ama genel işlemci kullanımı yaklaşık 80-90%, çünkü "Sistem (NT Kernel & Sistem")% 70'e kadar yükselir! DÜZENLEME: Ve RAM kullanımının, 15 saniye içinde periyodik olarak 1 GB'den fazla arttığını ve sonra aniden normal seviyesine geri döndüğünü fark ettim.
Belki aşağıdaki kod optimize edilebilir? :
namespace InteropBitmapTest{
using System;
using System.Drawing;
using System.Runtime.InteropServices;
using System.Windows;
using System.Windows.Interop;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using Color = System.Drawing.Color;
public partial class Window1 : Window
{
private System.Drawing.Bitmap gdiBitmap;
private Graphics graphics;
InteropBitmap interopBitmap;
const uint FILE_MAP_ALL_ACCESS = 0xF001F;
const uint PAGE_READWRITE = 0x04;
private int bpp = PixelFormats.Bgr32.BitsPerPixel/8;
private Random random;
private System.Windows.Forms.Timer timer = new System.Windows.Forms.Timer();
SolidBrush[] brushes = new SolidBrush[] { new SolidBrush(Color.Lime), new SolidBrush(Color.White) };
[DllImport("kernel32.dll", SetLastError = true)]
static extern IntPtr CreateFileMapping(IntPtr hFile,
IntPtr lpFileMappingAttributes,
uint flProtect,
uint dwMaximumSizeHigh,
uint dwMaximumSizeLow,
string lpName);
[DllImport("kernel32.dll", SetLastError = true)]
static extern IntPtr MapViewOfFile(IntPtr hFileMappingObject,
uint dwDesiredAccess,
uint dwFileOffsetHigh,
uint dwFileOffsetLow,
uint dwNumberOfBytesToMap);
public Window1()
{
InitializeComponent();
Loaded += Window1_Loaded;
WindowState = WindowState.Maximized;
timer.Tick += timer_Tick;
timer.Interval = 30;
random = new Random();
}
void Window1_Loaded(object sender, RoutedEventArgs e)
{
// create interopbitmap, gdi bitmap, get Graphics object
CreateBitmaps();
// start drawing 100 gdi+ rectangles every 30 msec:
timer.Start();
}
void timer_Tick(object sender, EventArgs e)
{
int width = 50;
// Draw 100 gdi+ rectangles :
for (int i = 0; i < 100; i++)
{
int left = random.Next((int)(ActualWidth - width));
int top = random.Next((int)(ActualHeight - width));
graphics.FillRectangle(brushes[left % 2], left, top, width, width);
}
interopBitmap.Invalidate(); // should only update video memory (and not copy the whole bitmap to video memory before)
}
void CreateBitmaps()
{
uint byteCount = (uint) (ActualWidth * ActualHeight * bpp);
//Allocate/reserve memory to write to
var sectionPointer = CreateFileMapping(new IntPtr(-1), IntPtr.Zero, PAGE_READWRITE, 0, byteCount, null);
var mapPointer = MapViewOfFile(sectionPointer, FILE_MAP_ALL_ACCESS, 0, 0, byteCount);
var format = PixelFormats.Bgr32;
//create the InteropBitmap
interopBitmap = Imaging.CreateBitmapSourceFromMemorySection(sectionPointer, (int)ActualWidth, (int)ActualHeight, format,
(int)(ActualWidth * format.BitsPerPixel/8), 0) as InteropBitmap;
//create the GDI Bitmap
gdiBitmap = new System.Drawing.Bitmap((int)ActualWidth, (int)ActualHeight,
(int)ActualWidth * bpp,
System.Drawing.Imaging.PixelFormat.Format32bppPArgb,
mapPointer);
// Get good old GDI Graphics
graphics = Graphics.FromImage(gdiBitmap);
// set the interopbitmap as Source to the wpf image defined in XAML
wpfImage.Source = (BitmapSource) interopBitmap;
}
}}
XAML:
<Window x:Class="InteropBitmapTest.Window1"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="Window1" Height="300" Width="300">
<Image Name="wpfImage" Stretch="None" />
</Window>
Uygulamanızı çalıştırmıyorken bu Sistem işlemi nasıl görünür? Ya da uygulamanız bir kesme noktasına ulaştığında mı? İlk düşüncem bu süreç bir çeşit kötü amaçlı yazılım. –
Sonra herhangi bir cpu tüketmez. Ancak fark ettiğim bir başka şey ise RAM kullanımının 15 saniye içinde periyodik olarak 3 GB'ye yükselmesi ve normal seviyeye düşmesi ve bunun gibi bir şey olmasıdır. Dolayısıyla, her 30 msn'de bellek ayırmadan yüksek cpu kullanımı sonuçları görünüyor (interopbitmap.Invalidate() öğesinin çağrıldığı zamanlayıcı olayı). – fritz