是否有可能"杀死"一个线程BackgroundWorker?
在我的DoWork事件中,我无法检查取消标志,因为我有一个阻止调用外部COM接口或查询数据库.CancelAsync不会取消对COM的调用.
我该怎么办呢?任何建议将非常感谢.
提前致谢.
我调用了一个方法,它返回一个UIElement我使用的调用Dispatcher,下面是代码.
但是,Dispatcher调用的返回值总是为NULL,任何想法?
void backgroundWorker_DoWork(object sender, DoWorkEventArgs e)
{
var slides = (IList<UIElement>)e.Argument;
var bmpSlides = new List<UIElement>();
var imageService = new ImageService();
int count = 0;
foreach (UIElement slide in slides)
{
object retVal = slide.Dispatcher.Invoke(
new ThreadStart(() => imageService.GenerateProxyImage(slide)));
bmpSlides.Add(imageService.GenerateProxyImage(slide));
_backgroundWorker.ReportProgress(count / 100 * slides.Count);
count++;
}
e.Result = bmpSlides;
}
Run Code Online (Sandbox Code Playgroud) 与TWAIN通信的哪些部分可以放入另一个线程,例如BackgroundWorker?或者:是否可以拆分处理图像传输的循环?
某些扫描仪驱动程序会在返回调用应用程序之前扫描所有图像,这会强制应用程序立即处理所有图像.这导致例如OutOfMemoryException或我的WPF应用程序中的奇怪行为,当突然所有事件(在每个扫描图像之后引发)必须立即处理.此外,应用程序会挂起,直到传输完成.
我正在使用TwainDotNet:http://code.google.com/p/twaindotnet/但我也在寻找一个通用的解决方案,描述消息过滤器以及与TWAIN独立的TwainDotNet的交互.包含TWAIN消息的工作流程就足够了.其他语言也很受欢迎,比较喜欢C或Deplhi.
DataSourceManager中消息过滤器的当前实现可以描述如下:
我用几台扫描仪测试了这个:
我不关心显示问题,而是关注被阻止的窗口和内存问题.将将图像传输到BackgroundWorker的循环导致几次崩溃,我无法调试.因为我考虑了WPF的线程问题.我也不知道如何拆分传输循环,这样,在传输一个图像后,程序返回到消息过滤器,消息可以标记为已处理.
快速问题 - 是否可以让两名后勤工作人员同时运行?我似乎记得尝试过这一次并得到一个错误,并且似乎还记得读到你只能有一个...我找不到另一个线程,谈论有多个明确但...
任何想法都非常感谢!
干杯
使用C#,WCF,WPF的客户端/服务器桌面应用程序.由于几乎所有操作都需要访问服务器(list/create/save/delete/etc),因此每个操作都有可能冻结整个UI.这是一个天真实现的例子,调用service.GetAll()可能需要"很长"的时间(超过几百毫秒):
private void btnRefresh_Click(object sender, RoutedEventArgs e)
{
vm.Users.Clear();
foreach (var user in service.GetAllUsers())
vm.Users.Add(user);
}
Run Code Online (Sandbox Code Playgroud)
(题外话:我很想知道为什么名单有AddRange和的ObservableCollection没有.)
BackgroundWorker 救援:
private void btnRefresh_Click(object sender, RoutedEventArgs e)
{
var worker = new BackgroundWorker();
worker.DoWork += (s, e) =>
{
Dispatcher.BeginInvoke((Action)delegate() { btnRefresh.IsEnabled = false; });
e.Result = service.GetAllUsers();
};
worker.RunWorkerCompleted += (s, e) =>
{
vm.Users.Clear();
foreach (var user in (List<UserDto>)e.Result)
vm.Users.Add(user);
Dispatcher.BeginInvoke((Action)delegate() { btnRefresh.IsEnabled = true; });
};
worker.RunWorkerAsync();
}
Run Code Online (Sandbox Code Playgroud)
(旁白:上面的代码已被简化,但这是它的要点.)
使用的代码BackgroundWorker …
我是WPF的初学者,在我的应用程序中我需要执行一系列初始化步骤,这些步骤需要10-15秒才能完成,在此期间我的UI变得无法响应.
我昨天使用的是后台工作者,但它没有更新我的窗口,事实上它被冻结了.不确定,但也许它不起作用,因为此控件仅适用于Windows窗体.
更新:
如果不是太麻烦,你能给我一个例子来使用替代方案吗?对于我的情况,程序将从一个数据库中获取一些值.
我正在开发一个显示多个TabItems 的支持工具TabControl.每个TabItem代表一个员工,在这些员工Tab的每个人中都有另一个TabControl包含额外TabItem的员工.这些TabItem代表该员工的Outlook文件夹(如"正在工作","已完成"等).这些文件夹中TabItem的每一个都包含一个ListBox绑定到与该Outlook文件夹相关ObservableCollection的MailItems的文件夹.这些不是巨大的收藏 - 每个只有十几件ListBox.虽然总的来说,所有人都TabItem可以想到100件左右.
我目前构建应用程序的方式是应用程序启动并使用相应的员工选项卡和子选项卡填充屏幕.这个过程相当快,我很高兴.我创建了一个静态Global.System.Timer文件,所有文件夹TabItem的代码隐藏都与之同步.因此,应用程序每5分钟清除一次ObserverableCollection并重新扫描Outlook文件夹.
问题是扫描过程使应用程序停止.我尝试使用a BackgroundWorker从Outlook收集邮件作为后台进程,然后将一个List<MailItem>对象传递给一个RunWorkerCompleted方法,然后运行一个this.Dispatcher.BeginInvoke清除相应的进程,ObservableCollection然后将项目从List<MailItem>后面添加到ObservableCollection.我甚Dispatcher至将此设置为较低优先级.
尽管如此,在扫描/填充ListBox过程中应用程序非常笨重.我不清楚如何更好地设计这个,我承认我对此有些新意.我意识到清除每个ObservableCollections都是低效的,但Outlook文件夹更改事件并不是特别可靠,所以我需要每隔一段时间重新扫描一次以确保所有MailItems都被表示.
下面是我的WPF控件的代码,其中包含ListBox.请记住,这些ListBox控件中大约有10个同时处于活动状态.
// This entire UserControl is essentially a ListBox control
public partial class TicketListView : …Run Code Online (Sandbox Code Playgroud) 我是第一次成立背景工作者.它主要是在代码运行时工作,我的停止/取消按钮正在工作.但是,我也在尝试报告更新进度条的进度,但我根本无法解决这个问题.
我从点击按钮启动代码,运行此代码:
backgroundWorker1.WorkerSupportsCancellation = true;
backgroundWorker1.WorkerReportsProgress = true;
backgroundWorker1.RunWorkerAsync();//this invokes the DoWork event
Run Code Online (Sandbox Code Playgroud)
我的Do_Work方法:
private void backgroundWorker1_DoWork(object sender, DoWorkEventArgs e)
{
BackgroundWorker worker = sender as BackgroundWorker;
int j = 0;// Count cumulative imported files
int countDupFiles = 0;// Count number of previously imported csv files
int countImportedFiles = 0;// Count imported files
foreach (string folderPath in csvDirList)
{
string[] csvFileNames = Directory.GetFiles(@folderPath, "*.csv");
frmImportCsvData.replaceAll(csvFileNames, folderPath + "\\", "");
for (int i = 0; i < csvFileNames.Length; i++, j++)
{ …Run Code Online (Sandbox Code Playgroud) 我希望在服务器启动时在我的rails应用程序中订阅mqtt主题,并保持订阅始终处于活动状态并正在运行.
我正在使用这个mqtt gem进行mqtt通信:https: //github.com/njh/ruby-mqtt
这就是我现在所拥有的:
在application.rb中:
config.after_initialize do
mqttSub = BackgroundMQTT.new
mqttSub.run
end
Run Code Online (Sandbox Code Playgroud)
BackgroundMQTT类:
class MQTTSubscriber
def run
Thread.new do
MQTT::Client.connect(:host => 'localhost', :port => 1883,) do |c|
c.get('#') do |topic,message|
puts "#{topic}: #{message}"
#Do things, access activerecord etc.
end
end
end
end
end
Run Code Online (Sandbox Code Playgroud)
所以基本上mqtt订阅从after_initialize方法开始,据我所知,不会自动停止?
另外如您所见,我正在线程中运行订阅,否则我的rails应用程序将停止执行除听取mqtt订阅之外的任何其他操作.
这似乎至少在前几分钟有效.
我不确定这是否是我想做的事情的推荐方式.这会导致我没有考虑过的任何问题吗?这样做的推荐方法是什么?
我有一个BackgroundWorker和一个ProgressBar.工作时,BackgroundWorker会运行三重for循环并将进度报告给ProgressBar.
目前,报告的进度只是最外层循环(xProgress)的进度,它起作用,但运行不顺畅.目标是让ProgressBar还考虑内部循环的进度百分比,以便ProgressBar更顺畅,更准确地更新.
DoWork方法:
private void bgw_DoWork(object sender, DoWorkEventArgs e)
{
int xMax, yMax, zMax;
xMax = 10;
for (int x = 1; x <= xMax; x++)
{
yMax = 5;
for (int y = 1; y <= yMax; y++)
{
zMax = new Random().Next(50, 100);
for (int z = 1; z <= zMax; z++)
{
Thread.Sleep(5); /// The process
double xProgress = (double)x / (double)xMax;
double yProgress = (double)y / (double)yMax;
double zProgress = (double)z / (double)zMax;
/// The progress …Run Code Online (Sandbox Code Playgroud) backgroundworker ×10
c# ×7
wpf ×4
.net ×3
dispatcher ×2
hwnd ×1
logic ×1
math ×1
mqtt ×1
progress-bar ×1
ruby ×1
twain ×1
wcf ×1