WPF - 跨线程事件



我的问题是我想使用新线程在画布中添加项目。所以我有多个方法(底部的示例(,它们生成例如图像并设置一些属性。然后,他们应该回调生成的事件。

以下是我调用的用于为画布生成想法的线程的一部分:

    //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);                
});

最新更新