fix: marshal timer callbacks to UI thread to prevent GDI+ threading exception
System.Timers.Timer fires on thread pool threads, causing GraphicsPath objects to be accessed concurrently by hover detection and OnPaint, triggering "Object is currently in use elsewhere" in DrawParts. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -621,30 +621,30 @@ namespace OpenNest.Controls
|
||||
|
||||
private void redrawTimer_Elapsed(object sender, System.Timers.ElapsedEventArgs e)
|
||||
{
|
||||
Invalidate();
|
||||
if (IsDisposed || !IsHandleCreated) return;
|
||||
BeginInvoke(new System.Action(Invalidate));
|
||||
}
|
||||
|
||||
private void hoverTimer_Elapsed(object sender, System.Timers.ElapsedEventArgs e)
|
||||
{
|
||||
if (IsDisposed || !IsHandleCreated) return;
|
||||
BeginInvoke(new System.Action(HoverCheck));
|
||||
}
|
||||
|
||||
private void HoverCheck()
|
||||
{
|
||||
var graphPt = PointControlToGraph(hoverPoint);
|
||||
LayoutPart hitPart = null;
|
||||
try
|
||||
|
||||
for (var i = parts.Count - 1; i >= 0; --i)
|
||||
{
|
||||
for (var i = parts.Count - 1; i >= 0; --i)
|
||||
if (parts[i].Path.GetBounds().Contains(graphPt) &&
|
||||
parts[i].Path.IsVisible(graphPt))
|
||||
{
|
||||
if (parts[i].Path.GetBounds().Contains(graphPt) &&
|
||||
parts[i].Path.IsVisible(graphPt))
|
||||
{
|
||||
hitPart = parts[i];
|
||||
break;
|
||||
}
|
||||
hitPart = parts[i];
|
||||
break;
|
||||
}
|
||||
}
|
||||
catch (InvalidOperationException)
|
||||
{
|
||||
// GraphicsPath in use by paint thread — skip this hover tick
|
||||
return;
|
||||
}
|
||||
|
||||
hoveredPart = hitPart;
|
||||
showTooltip = hitPart != null;
|
||||
|
||||
Reference in New Issue
Block a user