簡體   English   中英

Graphics.DrawString() 上的 AccessViolation

[英]AccessViolation on Graphics.DrawString()

我有一個 windows 表格,上面有一些數字(此時只有一個數字)並定期刷新它們(數字是隨機生成的)。 更新過程在與應用程序不同的線程中進行,因此表單可以接收用戶單擊按鈕、window 調整大小等事件。主要方法:

class Program {       
        static void Main(string[] args) {
            Form o = new Overlay();
            Application.Run(o);
        }
    }

表格 class:

public partial class Overlay : Form {
        Graphics g;
        Drawer drawer;
        public Overlay() {
            InitializeComponent();
            TopMost = true;
            TransparencyKey = Color.Black;
            BackColor = TransparencyKey;
            CheckForIllegalCrossThreadCalls = false;

            g = CreateGraphics();
            drawer = new Drawer();
        }

        protected override void OnLoad(EventArgs e) {
            base.OnLoad(e);
            Thread upd = new Thread(mainLoop);
            upd.Start();
        }

        void mainLoop() {
            while (true) {
                NetCoreEx.Geometry.Rectangle r;
                GetWindowRect(Handle, out r);
                Refresh();
                drawer.Update(g, new Rectangle(r.Left, r.Top, r.Width, r.Height));
            }
        }

抽屜:

class Drawer {
        Font font;

        public Drawer() {
            string workingDir = Environment.CurrentDirectory;
            string projDir = Directory.GetParent(workingDir).Parent.FullName;
            PrivateFontCollection collection = new PrivateFontCollection();
            collection.AddFontFile(projDir + "\\Resources\\Athelas-Regular.ttf");
            FontFamily fontFamily = new FontFamily("Athelas", collection);
            font = new Font(fontFamily, 16);
        }

        
        public void Update(Graphics g, Rectangle rect) {
            string stats = new Random().NextDouble().ToString();
            g.DrawString(stats, font, Brushes.Aqua, rect.Width / 2, (int)(rect.Height * 0.75));
        }
    }

代碼對我來說看起來很簡單,但由於某種原因,在正常運行 5-10 秒后,應用程序突然崩潰,並在 DrawString 方法上出現 System.AccessViolateException ... Stacktrace

at System.Drawing.SafeNativeMethods.Gdip.GdipDrawString(HandleRef graphics, String textString, Int32 length, HandleRef font, GPRECTF& layoutRect, HandleRef stringFormat, HandleRef brush)
   at System.Drawing.Graphics.DrawString(String s, Font font, Brush brush, RectangleF layoutRectangle, StringFormat format)
   at System.Drawing.Graphics.DrawString(String s, Font font, Brush brush, Single x, Single y)
   at OverlayStatistics.Scripts.Drawer.Update(Graphics g, Rectangle rect) in C:\Users\Гриша\source\repos\OverlayStatistics\Scripts\Drawer.cs:line 30
   at OverlayStatistics.Overlay.mainLoop() in C:\Users\Гриша\source\repos\OverlayStatistics\Scripts\Overlay.cs:line 50
   at System.Threading.ExecutionContext.RunInternal(ExecutionContext executionContext, ContextCallback callback, Object state, Boolean preserveSyncCtx)
   at System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state, Boolean preserveSyncCtx)
   at System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state)
   at System.Threading.ThreadHelper.ThreadStart()

我花了很多時間調試,但仍然不知道我做錯了什么,有什么幫助嗎?

發生的情況是FontFamily實例被釋放並導致內部 GDI 調用崩潰。 您可以像這樣加速行為:

public void Update(Graphics g, Rectangle rect)
{
    string stats = new Random().NextDouble().ToString();
    g.DrawString(stats, font, Brushes.Aqua, rect.Width / 2, (int)(rect.Height * 0.75));
    GC.Collect(); // a good way to check for dispose issues
}

有多種方法可以修復它,例如只需確保FontFamily實例也是Drawer的成員,即:

class Drawer {
    Font font;
    FontFamily fontFamily;


    public Drawer() {
        ...
        fontFamily = new FontFamily("Athelas", collection);
        font = new Font(fontFamily, 16);
    }

    public void Update(Graphics g, Rectangle rect) {
        string stats = new Random().NextDouble().ToString();
        g.DrawString(stats, font, Brushes.Aqua, rect.Width / 2, (int)(rect.Height * 0.75));
    }
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM