我正在修改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) 我似乎无法找到一种简单的方法来确定线程池何时完成所有排队的任务。我在这里找到了一些答案,但没有一个可以帮助我。
为了简单起见,我们说:
for (int i=0;i<10;i++)
{
threadpool.queueuserworkitem(Go);
}
void Go()
{
Console.WriteLine("Hello");
}
Run Code Online (Sandbox Code Playgroud)
那么,在所有 10 个后台线程完成后,我该如何发送最终的“全部完成”console.writeline 呢?
谢谢
我有一个可用的解决方案,可以将进度和文本报告给应用程序主窗体上的进度条和标签.我现在已经将我的工作方法移动到一个类,以便可以跨多个表单等访问它们.
在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) 我对使用事件处理程序和后台工作人员不熟悉,所以我可能会在这里遗漏一些完全明显的东西。尽管如此,我两天来一直在努力解决这个问题,所以我想我不妨看看有人说了什么。
我有一个名为 SqlExpressDownloader 的后台工作者。它在我的程序开始时开始运行,其余工作运行,然后它应该等待方法中的操作SqlExpressDownloader_DoWork()完成才能继续。唯一的问题是,由于某种原因,每当我这样做时while(SqlExpressDownloader.IsBusy),它总是响应为忙碌,因此将永远等待。
事件处理程序的代码在这里:
private void SqlExpressDownloader_DoWork(object sender, DoWorkEventArgs e)
{
string sSource = string.Format("{0}\\{1}", Paths.Settings_Common, "sqlexpr_x64_enu.exe");
Debug.WriteLine(sSource);
Debug.WriteLine("http://www.elexioamp.com/Install/redistributables/sql2008r2express/sqlexpr_x64_enu.exe");
if (!System.IO.File.Exists(sSource))
{
WebClient oWebClient = new WebClient();
oWebClient.DownloadProgressChanged += DownloadProgressChanged;
oWebClient.DownloadDataCompleted += DownloadComplete;
oWebClient.DownloadFileAsync(new System.Uri("http://www.elexioamp.com/Install/redistributables/sql2008r2express/sqlexpr_x64_enu.exe"), sSource);
while (oWebClient.IsBusy)
{
Thread.Sleep(100);
}
e.Result = "";
DownloadFinished = true;
}
}
Run Code Online (Sandbox Code Playgroud)
我看过代码,也看过它完成这个方法。我什至return在之后添加了一个DownloadFinished = true,但它仍然响应为忙。我想知道的是如何让后台工作人员响应不忙。
编辑事件全部添加到构造函数中,如下所示:
SqlExpressDownloader = new BackgroundWorker();
SqlExpressDownloader.DoWork += new DoWorkEventHandler(this.SqlExpressDownloader_DoWork);
SqlExpressDownloader.RunWorkerCompleted += new RunWorkerCompletedEventHandler(this.SqlExpressDownloader_RunWorkerCompleted);
Run Code Online (Sandbox Code Playgroud)
看起来RunWorkerCompleteEventHandler像这样:
private void SqlExpressDownloader_RunWorkerCompleted(object …Run Code Online (Sandbox Code Playgroud) 我使用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 MCIATS1Worker = new BackgroundWorker();
private AutoResetEvent _MCIATS1WorkerResetEvent = new AutoResetEvent(false);
public MainWindow()
{
InitializeComponent();
MCIATS1Worker = new BackgroundWorker();
MCIATS1Worker.DoWork += new DoWorkEventHandler(MCIATS1Worker_DoWork);
MCIATS1Worker.WorkerReportsProgress = true;
MCIATS1Worker.WorkerSupportsCancellation = true;
MCIATS1Worker.RunWorkerCompleted += new RunWorkerCompletedEventHandler(MCIATS1_RunWorkerCompleted);
for (int i = 1; i <= 10; i++)
{
//some code
MCIATS1Worker.RunWorkerAsync();
_MCIATS1WorkerResetEvent.WaitOne();
}
}
Run Code Online (Sandbox Code Playgroud)
DoWork 和 runworkercompleted
void MCIATS1Worker_DoWork(object sender, DoWorkEventArgs e)
{
//do something here
}
void MCIATS1_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
{
MessageBox.Show("hello world");
_MCIATS1WorkerResetEvent.Set();
}
Run Code Online (Sandbox Code Playgroud)
由于某些原因,在循环完成之前不会触发 MCIATS1_RunWorkerCompleted。显然,WaitOne 正在控制循环。
这是我的问题, …
我正在学习 Udacity Android Kotlin 开发人员课程。在其中一课中,讲师教授了如何使用 WorkManager 执行后台任务,始终在后台缓存数据,以便在应用程序启动时显示新数据。
因此,启动 WorkManager 定期刷新数据的代码是在应用程序的主应用程序中定义的。
class DevByteApplication : Application() {
/**
* onCreate is called before the first screen is shown to the user.
*
* Use it to setup any background tasks, running expensive setup operations in a background
* thread to avoid delaying app start.
*/
val applicationScope = CoroutineScope(Dispatchers.Default)
override fun onCreate() {
super.onCreate()
Timber.plant(Timber.DebugTree())
delayedInit()
}
private fun delayedInit() = applicationScope.launch {
setupRecurringWork()
}
private fun setupRecurringWork() {
val constraints = …Run Code Online (Sandbox Code Playgroud) backgroundworker ×10
c# ×5
.net ×2
winforms ×2
android ×1
async-await ×1
asynchronous ×1
c++ ×1
createthread ×1
data-binding ×1
kotlin ×1
rubygems ×1
threadpool ×1
wpf ×1