Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/.net/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
.net 在后台进程中访问WPF流程文档_.net_Wpf_Flowdocument_Background Process - Fatal编程技术网

.net 在后台进程中访问WPF流程文档

.net 在后台进程中访问WPF流程文档,.net,wpf,flowdocument,background-process,.net,Wpf,Flowdocument,Background Process,在后台访问WPF流程文档 我的问题涉及在WPF的后台访问UI对象。我见过几十个示例应用程序,它们都很简单,易于操作,其中95%告诉你如何显示进度条。那不是我想要的 我的问题是:我想通过访问RichTextBox中的FlowDocument来执行一个长任务(或许多长任务)。确切的任务在这里并不相关,但一个例子可能是扫描文档,并计算特定单词出现的次数,或者有多少个红色字符……。在一个很长的文档中,这些任务可能相当耗时,如果在前台完成,将大大占用UI并使其无响应。我只想解析FlowDocument;我

在后台访问WPF流程文档

我的问题涉及在WPF的后台访问UI对象。我见过几十个示例应用程序,它们都很简单,易于操作,其中95%告诉你如何显示进度条。那不是我想要的

我的问题是:我想通过访问RichTextBox中的FlowDocument来执行一个长任务(或许多长任务)。确切的任务在这里并不相关,但一个例子可能是扫描文档,并计算特定单词出现的次数,或者有多少个红色字符……。在一个很长的文档中,这些任务可能相当耗时,如果在前台完成,将大大占用UI并使其无响应。我只想解析FlowDocument;我不想对它做任何更改

这就是我想做的事情。显而易见的解决办法是在后台进行,但问题是……如何进行?我已经得到了一个看似正确的答案,但对我来说它并不“感觉正确”,这就是为什么我在这里寻求帮助

我的“解决方案”

我下面的“解决方案”使用BackgroundWorker调用UI对象的调度程序,以确保访问正确的线程……并且它“似乎”完成了这项工作。但这是真的吗?。。。。。。。。。。。。。。 我已经大大简化了我的“解决方案”,以便于(我希望)遵循我正在做的事情

WithEvents worker作为后台工作人员
私有委托子委托子委托子()
将文档作为流程文档进行私有化
''' 
''触发后台任务。可以从主代码块中的任何位置调用
''' 
私有子开始背景任务()
worker=新的后台工作人员
worker.RunWorkerAsync()
端接头
''' 
''在后台,将作业交给UI对象的调度程序
''' 
私有子HandleWorkerDoWork(ByVal sender作为对象,ByVal e作为DoWorkerVentargs)处理worker.DoWork
将优先级设置为System.Windows.Threading.DispatcherPriority
将长时间运行的任务设置为DelegateSub
“(1)定义分派器要使用的委托
长时间运行任务=新的被委派者子任务(时间消耗任务的地址)
'(2)根据需要设置调度程序优先级
优先级=System.Windows.Threading.DispatcherPriority.Background
(3)将作业添加到FlowDocument的调度程序任务中
document.Dispatcher.BeginInvoke(长时间运行任务,优先级)
端接头
''' 
''其逻辑访问但不更改UI对象的Sub
'''  
私有子DoTheTimeConsumingTask()
“比如。。。。。。
对于文档中的每个bl As块。块
“……做点什么
下一个
端接头
虽然这似乎是可行的,但在我看来,问题在于,除了使用BackgroundWorker触发任务外,几乎所有长时间运行的任务都由UI对象的调度程序处理。所以后台工作人员实际上没有做任何工作。这是我关心的部分;如果调度员忙着做所有的工作,我看不出我是如何得到任何东西的

选项2

因此,在我看来更符合逻辑的是,我最好“稍微扭转一下”,并将调度程序的委托设置为指向实例化并启动BackGroundWorker的子线程(我的想法是调度程序线程将拥有BackGroundWorker的线程),并完成后台员工嫁妆活动中的所有工作。“感觉”是对的

所以我尝试了这个:

WithEvents worker作为后台工作人员
私有委托子委托子委托子()
将文档作为流程文档进行私有化
''' 
''触发后台任务。可以从主代码块中的任何位置调用
''' 
私有子开始背景任务()
将优先级设置为System.Windows.Threading.DispatcherPriority
将任务设置为委派子任务
“(1)定义分派器要使用的委托
任务=newdelegatesub(RunWorker的地址)
'(2)根据需要设置调度程序优先级
优先级=System.Windows.Threading.DispatcherPriority.Normal
(3)将作业添加到调度程序的任务中
document.Dispatcher.BeginInvoke(任务,优先级)
端接头
''' 
''创建并启动新的BackGroundWorker对象
''' 
私有子RunWorker()
Worker=新的后台工作人员
Worker.RunWorkerAsync()
端接头
''' 
''在DoWork事件中执行长任务
''' 
私有子HandleWorkerDoWork(ByVal sender作为对象,ByVal e作为DoWorkerVentargs)处理worker.DoWork
DoTheTimeConsumingTask()
端接头
''' 
''其逻辑访问但不更改UI对象的Sub
'''  
私有子DoTheTimeConsumingTask()
“比如。。。。。。
对于文档中的每个bl As块。块
“……做点什么
下一个
端接头
在我看来,这一切似乎更符合逻辑。我猜测调度器将拥有BackgroundWorker,而BackgroundWorker将完成所有的长时间工作,并且所有内容都将在UI线程上。嗯……逻辑思维就到此为止……(WPF通常是致命的!)……事实并非如此。它会因通常的“不同线程”错误而崩溃。因此,经过再三考虑,似乎是一个更加优雅的解决方案,结果却是一个失败者

我的问题如下:

  • 我的“解决方案”是不是一个解决方案
  • 我哪里做错了
  • 如何改进“解决方案”,使调度员不被长任务束缚……这正是我试图避免的情况 还有一个问题。请注意,我必须使用FlowDocument的Dispatcher来完成这项工作。如果改为使用System.Windows.Threading.Dispatcher.CurrentDispatcher,则不会调用委托子(DoTheTimeConsumingTask),因此,无论出于何种目的,都不会发生任何事情。有人能解释一下为什么不行吗

    我不是作为第一个停靠港来找你的。我试过打瞌睡