我的问题是我想使用新线程在Canvas中添加Items。所以我有多个方法(底部的一个例子),它们生成例如一个Image并设置一些属性。然后他们应该通过一个事件回调生成的思考。
以下是我调用为canvas生成think的线程的一部分:
//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连接。这需要一些时间,所以我想在画布中添加元素asyncronly。
问题是我无法访问Canvas,因为它说我试图访问另一个线程。
抱歉,英语不是我的第一语言。
答案 0 :(得分:0)
您不想直接使用Canvas
项,因为它存在于gui线程中。你想要使用的调用应该是通用的,例如我在ViewModel上作为静态的调用:
public static void SafeOperationToGuiThread(Action operation)
{
System.Windows.Application.Current?.Dispatcher?.Invoke(operation);
}
然后你可以从另一个线程调用该操作,例如:
SafeOperationToGuiThread(() =>
{
var uiElem = ui;
canvas.Children.Add(uiElem);
});