我的问题是我想使用新线程在画布中添加项目。所以我有多个方法(底部的示例(,它们生成例如图像并设置一些属性。然后,他们应该回调生成的事件。
以下是我调用的用于为画布生成想法的线程的一部分:
//Here I create the event in the seconde Thread
public delegate void OnItemGenerated(UIElement elem);
public event OnItemGenerated onItemGenerated;
public void ItemGenerated(UIElement ui)
{
if (onItemGenerated != null)
onItemGenerated(ui);
}
......
//This is how I generate for example an image
public void addImage(int x, int y, string path, int width, int height)
{
System.Drawing.Bitmap bitmap = new System.Drawing.Bitmap(path);
Image img = new Image();
img.Source = getImage(bitmap);
img.Width = width;
img.Height = height;
Canvas.SetTop(img, y);
Canvas.SetLeft(img, x);
Application.Current.Dispatcher.Invoke(new Action(() => { ItemGenerated(img); }), DispatcherPriority.ContextIdle);
}
然后在主线程上,我想将回调的 UIElement 添加到画布中。
banner.onItemGenerated += (ui) =>
{
var uiElem = ui;
this.canvas.BeginInvoke(new Action(delegate () { this.canvas.Children.Add(uiElem); }));
};
这就是我启动线程的方式:
Thread t2 = new Thread(delegate ()
{
banner.GenerateImage(p);
});
t2.SetApartmentState(ApartmentState.STA);
t2.Start();
我这样做的原因是因为某些元素需要连接到 TelNet 连接。这需要一些时间,所以我想在 Canvas 异步器中添加元素。
问题是我无法访问 Canvas,因为它说我尝试访问不同的线程。
对不起,英语不是我的第一语言。
您不想直接使用 Canvas
项,因为它位于 gui 线程中。您要使用的调用应该是通用的,例如我在 ViewModel 上作为静态的
public static void SafeOperationToGuiThread(Action operation)
{
System.Windows.Application.Current?.Dispatcher?.Invoke(operation);
}
然后,您可以从其他线程调用该操作,例如:
SafeOperationToGuiThread(() =>
{
var uiElem = ui;
canvas.Children.Add(uiElem);
});