WPF - 跨线程事件

时间:2017-02-05 15:25:03

标签: c# wpf multithreading canvas

我的问题是我想使用新线程在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,因为它说我试图访问另一个线程。

抱歉,英语不是我的第一语言。

1 个答案:

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