Warning: file_get_contents(/data/phpspider/zhask/data//catemap/7/sql-server/25.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 如何使用另一个线程中的新对象更新属性?_C#_.net_Wpf_Multithreading_Xaml - Fatal编程技术网

C# 如何使用另一个线程中的新对象更新属性?

C# 如何使用另一个线程中的新对象更新属性?,c#,.net,wpf,multithreading,xaml,C#,.net,Wpf,Multithreading,Xaml,在主线程上设置另一线程的属性时遇到问题 这就是我目前所做的: XAML: 销钉法: 当我在Dispatcher.BeginInvoke的主体内创建ReportPreviewView时,我没有得到异常: public void DoWork(object sender) { //I create the relavant ViewModel ReportViewModel reportViewModel = new Repor

在主
线程
上设置另一
线程
属性时遇到问题

这就是我目前所做的:

XAML:

销钉法:

当我在
Dispatcher.BeginInvoke
的主体内创建
ReportPreviewView
时,我没有得到
异常:

    public void DoWork(object sender)
        {
            //I create the relavant ViewModel
            ReportViewModel reportViewModel = new ReportViewModel(SessionContext, Mediator, Parent.ReportRequest, false);

            Dispatcher.BeginInvoke((Action)(() =>
                        {
                            //Create the relevant View
                            ReportPreviewView reportPreviewView = new ReportPreviewView(reportViewModel) { ReportName = Parent.ReportRequest.Report.ReportName };
                            ViewModel.ReportView = reportPreviewView;
                        }));
        }
但这是不对的。它冻结了我的UI
线程
。创建
ReportPreviewView
需要很长时间

因此,我将
ReportPreviewView
的创建移到
Dispatcher.BeginInvoke
之外:

public void DoWork(object sender)
    {
        ReportViewModel reportViewModel = new ReportViewModel(SessionContext, Mediator, Parent.ReportRequest, false);

        ReportPreviewView reportPreviewView = new ReportPreviewView(reportViewModel) { ReportName = Parent.ReportRequest.Report.ReportName };

        Dispatcher.BeginInvoke((Action)(() =>
                    {
                        reportLoaderViewModel.ReportView = reportPreviewView;
                    }));
    }
PropertyChanged
一触发,我就会得到以下异常:

调用线程无法访问此对象,因为其他线程拥有它


你知道我该怎么做吗

您必须在UI调度程序线程上创建UI元素。无法逃脱。所以当你说

创建ReportPreviewView需要很长时间

你分析过为什么吗?它是否有图纸、动画、厚重样式、非虚拟化面板(如画布)?它的构造函数中是否有一些需要时间才能完成的代码

如果是这样,请重新考虑您的UI设计


在WPF中,用户界面总是冻结,以查看大量视图。即使您使用XAMLReader/Writer反序列化视图,视图对象的创建和托管也必须在UI线程上进行。

嗯,不确定这是否有帮助,但如果您的
ReportPreviewView
复制构造函数是轻量级的,您可能只想在
beginInvoke
中复制该对象,并使用它设置
ReportView
。但我几乎可以肯定这是行不通的。试试看,霍维尔,这只是一行代码:)前传:谢谢你的回复。当我说创建ReportPreviewView需要很长时间。
时,构造函数有一些需要很长时间的代码。。。否如果您说,
重新考虑您的UI设计
,那么我应该更改什么?我是新来的
多线程
,所以我会边走边学…那么需要时间的代码可以被放到
BackgroundWorker
?是的,我可以做到。。。那么这是一个可行的解决方案吗?当然,我的构造函数中所有冗长的操作都必须在它们自己的
线程/任务中进行。后台工作程序是合适的,因为它提供了调度程序驱动的
工作完成
事件。它还提供了进度通知事件,也可以作为后台线程,在主应用程序关闭时关闭。它也是由线程池内部处理的。我尝试将
繁重的工作
放在后台工作程序中,但仍然没有成功。
ReportPreviewView
在构造函数内部创建了另一个视图,在新视图的构造函数内部有更多的
重载
。我尝试将所有的
繁重的
放在
任务/后台工作人员
中,但是我得到
调用线程必须是STA,因为许多UI组件都需要它。
。我被困住了,不知道从这里到哪里去。。。你有什么其他的建议我可以试试吗?
    public void DoWork(object sender)
        {
            //I create the relavant ViewModel
            ReportViewModel reportViewModel = new ReportViewModel(SessionContext, Mediator, Parent.ReportRequest, false);

            Dispatcher.BeginInvoke((Action)(() =>
                        {
                            //Create the relevant View
                            ReportPreviewView reportPreviewView = new ReportPreviewView(reportViewModel) { ReportName = Parent.ReportRequest.Report.ReportName };
                            ViewModel.ReportView = reportPreviewView;
                        }));
        }
public void DoWork(object sender)
    {
        ReportViewModel reportViewModel = new ReportViewModel(SessionContext, Mediator, Parent.ReportRequest, false);

        ReportPreviewView reportPreviewView = new ReportPreviewView(reportViewModel) { ReportName = Parent.ReportRequest.Report.ReportName };

        Dispatcher.BeginInvoke((Action)(() =>
                    {
                        reportLoaderViewModel.ReportView = reportPreviewView;
                    }));
    }