我对Timer
中的System.Timers
对象有一点问题,并使用它在GTK的C#绑定中设置ComboBox的选项;我得到了段错误,我认为这是因为当Timer
调用其中一个附加的Elapsed
回调时,它会在一个线程池中执行。以下是问题的一些示例代码:
combobox1
是使用MonoDevelop中的GUI设计器添加的Gtk ComboBox,MainWindow.cs
:
using System;
using System.Timers;
using System.Collections.Generic;
using Gtk;
public partial class MainWindow: Gtk.Window
{
List<string> cbOptions = new List<string>();
public MainWindow()
: base(Gtk.WindowType.Toplevel)
{
Build();
combobox1.Sensitive = false;
}
protected void OnDeleteEvent(object sender, DeleteEventArgs a)
{
Application.Quit();
a.RetVal = true;
}
public void SetOptions(List<string> options, string initial)
{
// Clear & repopulate
if (options?.Count > 0)
{
// Clear
for (int i = 0; i < cbOptions.Count; i++)
combobox1.RemoveText(0);
// Set
foreach (string opt in options)
combobox1.AppendText(opt);
// Set the default
combobox1.Active = options.IndexOf(initial);
combobox1.Sensitive = true;
cbOptions = options;
}
else
combobox1.Sensitive = false;
}
}
Program.cs
:
using System;
using System.Timers;
using System.Collections.Generic;
using Gtk;
namespace ComboBoxTest
{
class MainClass
{
static MainWindow win;
public static void Main(string[] args)
{
Application.Init();
win = new MainWindow();
win.Show();
Timer t = new Timer(2000.0);
t.Elapsed += SetCB;
t.Start();
Application.Run();
}
public static void SetCB(object sender, ElapsedEventArgs args)
{
List<string> options = new List<string>();
for (int i = 1; i <= 25; i++)
options.Add(string.Format("{0} 000 000 000", i));
Random r = new Random();
win.SetOptions(options, string.Format("{0} 000 000 000", r.Next(1, 25)));
}
}
}
是否有某种GUI线程我可以确保回调正在运行,所以我不能解决这个问题?如果您删除了Timer
代码,并在SetCB(null, null);
之前添加了对Application.Run();
的通话,您将会看到此功能符合预期。
答案 0 :(得分:1)
段错误是Mono错误,或者是GTK中错误使用线程的结果。请使用这个小工具来确定它是否是后者:https://github.com/slluis/gui-thread-check
答案 1 :(得分:1)
我想出了如何做到这一点。如果您正在使用多个线程,则需要将GTK GUI调用包含在委托中,并将其传递给 var trianguloGeometry = new THREE.Geometry();
trianguloGeometry.vertices.push(new THREE.Vector3(0,0,0));
trianguloGeometry.vertices.push(new THREE.Vector3(0,50,0));
trianguloGeometry.vertices.push(new THREE.Vector3(50,0,0));
trianguloGeometry.vertices.push(new THREE.Vector3(0,0,0));
trianguloGeometry.vertices.push(new THREE.Vector3(0,50,0));
trianguloGeometry.vertices.push(new THREE.Vector3(-50,0,0));
trianguloGeometry.faces.push(new THREE.Face3(0,1,2));
trianguloGeometry.faces.push(new THREE.Face3(3,4,5));
trianguloGeometry.computeFaceNormals();
trianguloGeometry.computeFlatVertexNormals ();
var triangulo = new THREE.Mesh(
trianguloGeometry,
new THREE.MeshLambertMaterial({
color:'red',
side:THREE.DoubleSide,
vertexColors:THREE.FaceColors
}),
);
scene.add(triangulo);
triangulo.castShadow = true;
。
e.g。
Gtk.Application.Invoke()
这是安全的&amp;正确的方法。