运行缓慢可能需要用户交互的流程 [英] Slow running Process that might require user interaction

查看:75
本文介绍了运行缓慢可能需要用户交互的流程的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

大家好,



好​​的,所以我不确定这是否可行/可取,所以请寻求指导。

基本上我正在开发一个通过excel电子表格(不是excel)读取的进程。

对于每一行,进程会查看辅助数据存储,以根据中的两列来提取信息。 excel表。大多数情况下,每次只会找到一个结果,但偶尔会发生以下情况:



a)找到0个结果

b)找到了1个以上的结果



我希望能够向用户显示一个表单,以便他们可以改变搜索到的文本,或者他们可以选择跳过记录。



这是处理超过2000行的大文件,并且还使用相当慢的API来查询第二个数据存储(它是第三方所以必须以这种方式访问​​它。



理想情况下我想在不同的线程上运行处理到主UI,这是一个MVVM WPF应用程序,所以我可以更新显示每个处理行的进度的日志。



现在,我对背景工作者没关系,但我不知道我怎么能拥有使用后台工作程序在奇数记录上输入UI?这可能吗?

有没有更好的方法我可以利用线程来做到这一点并仍然保持响应式用户界面并在需要时提示?



在此先感谢。

Hi guys,

Okay, so I'm not sure if this is possible/advisable so looking for guidance with this one please.
Basically I am developing a process that reads through an excel spreadsheet (not in excel).
For each row the process looks into a secondary data store to pull out information based on two columns in the excel sheet. Most of the time only one result will be found each time, however occasionally the following will occur:

a) 0 results are found
b) more than 1 result is found

I want to be able to display a form to the user so they can alter the text it searched on, or they can choose to skip the record.

This is processing large files with in-excess of 2000 rows and is also using a fairly slow API for querying the second data store (it is third party so have to access it this way).

I would ideally like to run the processing on a different thread to the main UI which is a MVVM WPF application so that I can update a log showing progress for each row that is handled.

Now, I'm okay with a background worker, but I'm not sure how I can have UI input on the odd records using a background worker? Is this possible?
Is there a better way I could utilize threading to do this and still maintain a responsive UI and have prompts as/when required?

Thanks in advance.

推荐答案

请参阅我对这个问题的评论。



替代方法 BackgroundWorker 正在使用通过构造函数创建的初步创建的线程,您可以保持睡眠状态(当然浪费没有CPU时间)并在任务被提供给它时​​激活。这是一个非常好且稳定的设计变体,因为您只在运行时的最开始分配所有相关资源。这样的限制由类 System.Threading.ManualResetEvent 完成:

http://msdn.microsoft.com/en-us/library/system.threading.manualresetevent.aspx [< a href =http://msdn.microsoft.com/en-us/library/system.threading.manualresetevent.aspxtarget =_ blanktitle =New Window> ^ ]。



您只需重置或发出事件线程句柄信号,并调用其方法 WaitOne 的线程进入等待状态事件句柄没有信号。线程将在发出信号或其他一些条件(中止或超时)时被唤醒。



这种行为的一种特殊形式,零浪费CPU可以是使用阻塞队列实现。请参阅我关于这个主题的文章:

用于线程通信和线程间调用的简单阻塞队列



如您所见,您可以向队列提供的一种项目可以是委托实例。这样,您可以立即将任务提供给线程,线程将等待任务,在等待状态中没有浪费CPU时间。 (这是可能的,因为线程是基于中断完成的。)



顺便说一下,这是如何调用委托实例到一些UI线程正在使用 Dispatcher ,这带来了其他问题:如何使用来自某些非UI线程的UI?



您无法从非UI线程调用与UI相关的任何内容。相反,您需要使用 Invoke System.Windows.Threading的方法。 Dispatcher (对于Forms或WPF)或 System.Windows.Forms.Control (仅限表单)。



您将在我过去的答案中找到有关其工作原理和代码示例的详细说明:

Control.Invoke()与Control.BeginInvoke() [ ^ ],

使用Treeview扫描仪和MD5的问题 [ ^ ]。



现在,我答应建议线程包装并激励它。请阅读我过去的答案:

线程包装器

带锁的线程包装器:多线程使用

带有事件的线程包装器



另请参阅有关线程的更多参考资料:

如何在vb中的其他线程上运行keydown事件。净 [ ^ ],

控制ev启用禁用+多线程后,ents不会触发 [ ^ ]。



-SA
Please see my comments to the question.

One approach alternative to the BackgroundWorker is using preliminary created thread, created through the constructor, which you can keep sleeping (wasting no CPU time for that, of course) and activate when the task is fed to it. This is a really good and stable variant of design, because you allocate all related resources only in the very beginning of runtime. Such throttling is done by the class System.Threading.ManualResetEvent:
http://msdn.microsoft.com/en-us/library/system.threading.manualresetevent.aspx[^].

You just reset or signal the event thread handle, and the thread calling its method WaitOne is put to the wait state of the event handle is non-signaled. The thread will be awaken when it is signaled or by some other conditions (abort or timeout).

One more specialized form of such behavior with zero-waste CPU can be achieved with the blocking queue. Please see my article on the topic:
Simple Blocking Queue for Thread Communication and Inter-thread Invocation.

As you can see, one kind of items you can feed to the queue could be delegate instances. This way, you can immediately feed tasks to the thread, and the thread will be waiting for the task, wasting no CPU time in the wait state. (And this is possible because threading is done based on interrupts.)

By the way, this is how invocation of the delegate instances to some UI thread is working with Dispatcher, which brings us to other problem: how to work with UI from some non-UI thread?

You cannot call anything related to UI from non-UI thread. Instead, you need to use the method Invoke or BeginInvoke of System.Windows.Threading.Dispatcher (for both Forms or WPF) or System.Windows.Forms.Control (Forms only).

You will find detailed explanation of how it works and code samples in my past answers:
Control.Invoke() vs. Control.BeginInvoke()[^],
Problem with Treeview Scanner And MD5[^].

Now, I promised to suggest thread wrapper and motivate it. Please read my past answers:
Thread wrapper,
Thread wrapper with lock: multithreading use,
Thread wrapper with event.

See also more references on threading:
How to get a keydown event to operate on a different thread in vb.net[^],
Control events not firing after enable disable + multithreading[^].

—SA


这篇关于运行缓慢可能需要用户交互的流程的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆