繁体   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