gpt4 book ai didi

c# - Graphics.DrawString() 上的 AccessViolation

转载 作者:行者123 更新时间:2023-12-04 01:08:29 26 4
gpt4 key购买 nike

我有一个 Windows 窗体,上面有一些数字(此时只有一个数字)并定期刷新它们(数字是随机生成的)。更新过程与应用程序在一个单独的线程中进行,因此表单可以接收用户单击按钮、调整窗口大小等事件。主要方法:

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

表单类:

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 而崩溃...堆栈跟踪

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));
}
}

关于c# - Graphics.DrawString() 上的 AccessViolation,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/65552667/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com