我对resque很新,但它看起来非常适合我的需求.
实际上,我正在尝试设置一个简单的测试应用程序,如:
require 'resque'
require 'resque/job_with_status'
class WordAnalyzer < Resque::JobWithStatus
@queue = "word_analysis"
def self.perform(word)
puts "About to do heavy duty analysis on #{word}"
sleep 3 # fake analysis here
# this would be something impressive
puts "Finished with analysis on #{word}"
end
end
Run Code Online (Sandbox Code Playgroud)
并创建一个后台工作者
WordAnalyzer.create(word)
Run Code Online (Sandbox Code Playgroud)
没有resque-status,它可以完美地工作(调用enqueue而不是创建worker).随着resque-status,我得到了一个
错误的参数数量(2为1)/.../resque_test/lib/word_analyzer.rb:6:在`perform'/.../.rvm/gems/ruby-1.9.2-p136/gems/resque- 1.16.1/lib/resque/job.rb:127:在`perform'中
我搜索了文档和代码,但没有找到将参数传递给resque-status工作的正确方法.可能吗?
提前致谢.
我在 winform 上有一个 DataGridView。我在表单的加载方法中动态添加 DatagridViewButtonColumn,按钮名称为 btnAction,其上显示的文本为“Process”。
因此,网格中的每一行的最后一列都会有这个“处理”按钮。
在此按钮的单击事件中,我使用 BackgroundWorker 来调用进行一些计算的方法。计算结束后,我需要在网格的该行中将单击的按钮文本更新为“已处理”。请问我该如何实现?
谢谢。
我需要确保BackgroundWoker在被调用之前不忙,所以我检查IsBusy并调用CancelAsync,如果它是:
if (bgWorker.IsBusy)
bgWorker.CancelAsync();
Run Code Online (Sandbox Code Playgroud)
但如果IsBusy属实,则在CancelAsync()说"BackgroundWorker不支持取消" 时会发生InvalidOperationException异常.
文档使用看起来很简单,所以我做错了什么?我该如何取消这份工作?
在尝试计算完成百分比时,我在这里错过了什么?我的百分比等式似乎返回了不正确的百分比.
Int32 counter = 0;
foreach (var vehicle in vehicles)
{
counter += 1;
Int32 percentage = (Int32)((double)counter * vehicles.Count()) / 100;
_worker.ReportProgress(percentage);
if (_worker.CancellationPending)
{
e.Cancel = true;
_worker.ReportProgress(0);
return;
}
}
Run Code Online (Sandbox Code Playgroud) 我有一个现有的 WPF 应用程序,它有几个部分。每个部分都是一个 UserControl,它实现了一个接口。
该接口指定了两种方法:void LoadData([...])和bool UnloadData()。
这些方法是由UI线程调用的,所以如果很耗时,我们需要在backgroundworker中完成我们的工作。
没有问题,LoadData因为我们可以异步更新 UI。问题在于 UnloadData()。
如果我们真的可以离开当前视图,这应该返回。
这是根据数据的当前状态(已保存/修改/无效)计算的:
问题在于“修改 - > 保存”。这是一种耗时的方法,因此为了尊重应用程序的理念,我们应该在后台线程中运行它(带有忙碌指示器)。
但是如果我们只是启动线程并进入下一节,它会向方法调用返回“true”,我们将直接启动下一个视图。
就我而言,在保存本地数据之前加载下一个视图可能是个问题。
所以:
有没有办法在返回“true”之前等待后台线程完成,而不阻塞 UI?
public bool UnloadData(){
if(...){
LaunchMyTimeConsumingMethodWithBackgroundWorker();
return true;//Only when my time consuming method ends
}
//[...]
}
Run Code Online (Sandbox Code Playgroud)
重要编辑 也许我不够清楚:我知道如何使用 BackgroundWorker 或 TPL。我的问题是父类(调用 UnloadData() 的那个类是一个我无法编辑的类(出于多种原因:它在另一个不会重新加载的 DLL 中,它已经与 70 多个用户控件一起使用,全部分开项目(dll),通过反射加载。
这不是我的选择,我觉得它不好,但我现在必须处理它。我主要是在寻找让我的方法等待我的方法返回的方法。我不确定这是否可能。但我正在寻找一种解决方法,它将为我节省数周的工作时间。
我正在使用后台工作人员来处理文件的加载以阻止我的 ui 冻结,但是似乎RunWorkerCompleted在我的DoWork事件完成之前就完成了(退出对话框时导致错误)......我做错了什么? 我最好在任务上做这个吗?
public static <T> LoadDesign(string xmlPath)
{
PleaseWait pw = new PleaseWait(xmlPath);
pw.ShowDialog();
return pw.design;
}
private PleaseWait(string xmlFile)
{
InitializeComponent();
bw = new BackgroundWorker();
bw.WorkerSupportsCancellation = true;
bw.DoWork += (s, e) =>
{
design = (Cast)DllCall containing XmlSerializer.Deserialize(...,xmlFile);
};
bw.RunWorkerCompleted += (s, e) => {
//Exit please wait dialog
this.Close();
};
if (!bw.IsBusy)
bw.RunWorkerAsync();
}
Run Code Online (Sandbox Code Playgroud)
我相信这个问题可能归结为我的后台工作人员正在调用一个 dll 而不是等待响应的事实。我试图添加检查,如while(design == null)无济于事..
Edit2 错误是 NRE,因为设计尚未加载,我可以轻松解决此问题,但宁愿让线程工作。
我正在尝试使用此方法更新列表框中的多个值:此方法的作用是复制指定目录的内容,但它将当前文件名输出到后台工作进程进度更改事件。
private bool CopyDirectory(string SourcePath, string DestinationPath, bool Recursive, BackgroundWorker worker, DoWorkEventArgs e)
{
List<string> Paths = new List<string>();
List<string> Files = new List<string>();
//for windows xp My documents
if(!Directory.Exists(SourcePath))
{
SourcePath = SourcePath.Replace(@"C$\Users\", @"C$\Documents and Settings");
int doccount = Regex.Matches(SourcePath, "Documents").Count;
//if source contains 2 documents
if(doccount > 1)
{
ReplaceLastOccurrence(SourcePath, "Documents", "My Documents");
}
}
//set file permissions
FileIOPermission f2 = new FileIOPermission(FileIOPermissionAccess.Read, SourcePath);
f2.AllLocalFiles = FileIOPermissionAccess.Read;
f2.Demand();
foreach (string StringPath in DirectoryList(SourcePath, Recursive, null))
Paths.Add(StringPath);
foreach (string …Run Code Online (Sandbox Code Playgroud) 我有一个BackgroundWorker为列表中的每个对象创建一个的函数,我现在想要做的是将创建的工作人员数量限制为 20,并在他们完成后处理列表中的下一项。我正在考虑使用队列,并在处理工作人员之前检查队列大小是否小于 20,然后创建工作人员并将其添加到队列中。我的问题是如何在完成后从队列中删除该项目?以及如何设置循环以等待工作人员可用?
编辑
我想我已经接近了,这就是我现在所拥有的,但问题是程序卡在了while循环中:
var myObjectList = new List<myObject>();
myObjectList = PopulateList();
BackgroundWorker bgw;
foreach (var obj in myObjectList)
{
bgw = new BackgroundWorker();
while(BgwList.Count >= 20); //getting stuck here, why?
BgwList.Add(bgw);
if(!bgw.IsBusy)
{
bgw.RunWorkerAsync(obj);
}
}
Run Code Online (Sandbox Code Playgroud)
BackgroundWorker完成后删除:
void BackgroundWorker_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
{
BgwList.Remove((BackgroundWorker)sender); //verified that bgw is being removed from list
//... other code
}
Run Code Online (Sandbox Code Playgroud) 我是一个没有经验的python程序员.
有没有办法使用backgroundworker,以便它在程序启动时启动并在程序关闭时关闭?
我想让它看一个按钮,按下时按钮返回1.因此,当程序在运行时,只要按钮= 1按钮就必须执行"此操作".
谁能帮我这个?
我对C#中的BackgroundWorker性能有一个奇怪的问题.我有一个应用程序,除其他外,使用BackgroundWorker来执行某些任务.Basicaly的任务如下:
public void simulate(Image imgSimulator)
{
simulador = new Simulator(imgSimulator);
simulador.setBackground(0);
Constants.finishSimulation = false;
BackgroundWorker bw = new BackgroundWorker();
bw.DoWork += run;
bw.RunWorkerAsync(imgSimulator);
}
public void run(object sender, DoWorkEventArgs e)
{
Image imgSimulator = (Image)e.Argument;
bool clear;
foreach (Program p in programs)
{
Resource r = p.getResource(0);
clear = true;
if (r is Text)
{
Text t = (Text)r;
clear = t.getClearPrev() == 1;
}
if (!clear)
{
simulador.setBackground(FontBitmap.COLOR_BLACK);
}
p.execute(simulador, imgSimulator);
if (Constants.finishSimulation)
{
break;
}
}
}
Run Code Online (Sandbox Code Playgroud)
上面代码中的主要函数是execute: …
backgroundworker ×10
c# ×7
.net ×2
winforms ×2
wpf ×2
datagridview ×1
listview ×1
percentage ×1
python ×1
resque ×1
ruby ×1
ui-thread ×1