我正在使用同时运行的5个BackgroundWorker对象用于特定目的,并且所有这些对象都必须更改相同的标签.我怎么做?
如何从多个线程修改表单呢?如果我想更改公共字符串,我该怎么做?
我有一个程序,它使用线程顺序执行耗时的进程.我希望能够监视每个线程的进度,类似于BackgroundWorker.ReportProgress/ ProgressChangedmodel的方式.我不能使用ThreadPool或BackgroundWorker由于我的其他限制.允许/公开此功能的最佳方法是什么.重载Thread该类并添加属性/事件?另一个更优雅的解决方案?
我正在修改Windows窗体以允许在UI保持响应的同时在后台加载数据.数据需要花费大量时间来检索和绑定.理想情况下,我会在后台执行这两项工作,但是我在后台应该做什么样的UI更新(如在主线程外部),这有些含糊不清.在后台显示数据检索和数据绑定的一个可靠示例将非常有用.
data-binding user-interface multithreading backgroundworker winforms
关于BGW长期运行的任何想法建议?
有谁知道一个与Rails 3一起使用的后台作业管理器?我听说过Starling和Workling,但我没有看到Rails 3的分叉.
我一直在寻找并发现执行后台工作和更新GUI的好方法是使用后台工作程序.但是,执行这个(愚蠢的)小任务(从1到10000计数)它不会更新标签内容,而是打印到调试!(当然这只是另一个项目的尖峰解决方案......)
这是代码:
public partial class MainWindow : Window
{
BackgroundWorker bw = new BackgroundWorker();
public MainWindow()
{
InitializeComponent();
}
private void button1_Click(object sender, RoutedEventArgs e)
{
bw.DoWork += new DoWorkEventHandler(bw_DoWork);
bw.ProgressChanged += new ProgressChangedEventHandler(bw_ProgressChanged);
bw.WorkerReportsProgress = true;
bw.RunWorkerCompleted += new RunWorkerCompletedEventHandler(bw_RunWorkerCompleted);
bw.RunWorkerAsync();
}
void bw_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
{
MessageBox.Show("DONE");
}
void bw_ProgressChanged(object sender, ProgressChangedEventArgs e)
{
label1.Content = "going here: "+e.ProgressPercentage;
Debug.WriteLine(e.ProgressPercentage);
}
void bw_DoWork(object sender, DoWorkEventArgs e)
{
for (int i=0; i < 10000; i++)
{
bw.ReportProgress((i*100)/10000);
} …Run Code Online (Sandbox Code Playgroud) 我有一个可用的解决方案,可以将进度和文本报告给应用程序主窗体上的进度条和标签.我现在已经将我的工作方法移动到一个类,以便可以跨多个表单等访问它们.
在worker方法中是BW.ReportProgress()将进度和文本推回到主窗体中的BackgroundWorker的语句.
为了更好地了解这里的文件布局:
MainScreen.cs
List repSelected = new List();
XMLandRar xXMLandRar = new XMLandRar();
private void Rarbtn_Click(object sender, EventArgs e)
{
GetReps();
//Run worker
if (!CreateRarBW.IsBusy)
{
CreateRarBW.RunWorkerAsync();
}
}
//Worker
private void CreateRarBW_DoWork(object sender, DoWorkEventArgs e)
{
xXMLandRar.RarFiles(repSelected);
}
//Progress reporting
private void CreateRarBW_ProgressChanged(object sender, ProgressChangedEventArgs e)
{
progBar.Value = e.ProgressPercentage;
Statuslbl.Text = e.UserState.ToString();
}
Run Code Online (Sandbox Code Playgroud)
然后我新创建的Class包含所有的worker方法,并将进度推送到主窗体.
XMLandRar.cs
public class XMLandRar
{
public void RarFiles(List repSelected)
{
int step = 100 / repSelected.Count();
int i = 0;
//Iterate …Run Code Online (Sandbox Code Playgroud) 我使用这个函数来搜索所选目录中的所有exe文件:
public static IEnumerable<string> GetFiles(string root, string searchPattern)
{
Stack<string> pending = new Stack<string>();
pending.Push(root);
while (pending.Count != 0)
{
var path = pending.Pop();
string[] next = null;
try
{
next = Directory.GetFiles(path, searchPattern);
}
catch { }
if (next != null && next.Length != 0)
foreach (var file in next) yield return file;
try
{
next = Directory.GetDirectories(path);
foreach (var subdir in next) pending.Push(subdir);
}
catch { }
}
}
Run Code Online (Sandbox Code Playgroud)
如何根据找到的文件数更新进度条状态?
我讨厌我的第一个问题似乎已被多次回答,但我仍然很难理解如何使用BackgroundWorker调用方法.
我正在使用一系列类和方法处理一个非常大的文本文件.用户选择工具条项后,整个过程开始.顺便说一下,它是这样的:
从用户弹出初始对话框的那一刻起,我想我可以将所有内容都包装到BackgroundWorker中,但我现在要做的就是将所有繁重工作的方法放入其自己的BackGroundWorker实例中.我也会添加一个ProgressBar,但是如果我能够让BackgroundWorker进程滚动,我想我可以处理它.
从顶部开始(伪代码用于示例目的.为简洁起见省略了许多内容):
private void ToolStripMenuItem_Click(object sender, EventArgs e)
{
string fileName = openSingleFile.FileName;
processFile(fileName);
}
static public void processFile(string fileName)
{
// many vars/loops exist but not shown
foreach (data in bigData)
{
processItem(stringA, stringB); // <-- this method is where the expensive work is done
x++;
}
}
Run Code Online (Sandbox Code Playgroud)
我创建了一个BackgroundWorker实例...:
private void backgroundWorker1_DoWork(object sender, DoWorkEventArgs e)
{
// Things go here
}
Run Code Online (Sandbox Code Playgroud)
...我已经尝试了很多东西来列出,所以我回到了上面的演示文稿的开头.
如果我了解BackgroundWorker,我需要执行以下操作:
用上面的代码替换上面代码中的processItem(stringA,stringB):
backgroundWorker1.RunWorkerAsync(processItem(stringA, stringB));
...然后做一些类型的DoWork呼叫?...然后进行某种类型的RunWorkerCompleted调用?
不知道为什么我的大脑会冻结,但是我花了很多时间在这上面并没有结果,我很尴尬.任何帮助将不胜感激.没有StackOverflow,我很久以前就会成为DOA.
仅供参考:我已经引用了其他SO帖子,MSDN和DotNetPerls示例.我想,我只是在概念上遗漏了一些东西.
我使用CreateThread函数在C++中编写类似C#BackgroundWorker的类.我的代码:
BackgroundWorker.h:
class BackgroundWorker
{
private :
HANDLE _threadHandle;
unsigned int _threadCallcounter;
DWORD _threadID;
public:
BackgroundWorker();
~BackgroundWorker();
virtual DWORD WINAPI Function(LPVOID vpPram);
}
Run Code Online (Sandbox Code Playgroud)
BackgroundWorker.cpp:
#include "BackgroundWorker.h"
void BackgroundWorker::DoWork()
{
this->_threadHandle = CreateThread(NULL,
0,this->Function,&this->_threadCallcounter,
0, &this->_threadID); // !!!***This part throws an error***!!!
}
Run Code Online (Sandbox Code Playgroud)
然后我创建了另一个派生自BackgroundWorker的类:
ListenThread.cpp:
class ListenThread :public BackgroundWorker
{
DWORD WINAPI Function(LPVOID vpPram)
{
//DO somthing...
return 0;
}
};
Run Code Online (Sandbox Code Playgroud)
但该行给了我以下错误:
非标准语法; 使用'&'创建指向成员的指针
backgroundworker ×10
c# ×6
.net ×3
winforms ×3
c++ ×1
createthread ×1
data-binding ×1
file-search ×1
progress-bar ×1
rubygems ×1
threadpool ×1
wpf ×1