我最近尝试使用backgroundworker而不是"经典"线程,我意识到它至少对我来说,比解决方案更多的问题.我有一个后台工作程序运行同步读取(在这种情况下来自serialPort)并在1个代码行中被阻止大约30秒,然后取消支持不是解决方案.我看到如果应用程序此时关闭(使用十字按钮和Application.Exit()),该过程将永远保持僵尸.
我需要一种强制中止或杀死backgroundworker线程的方法.
我的应用程序的用户将HTML类型转换为TextBox控件.
我希望我的应用程序在后台验证他们的输入.
因为我不想敲定验证服务,所以我尝试在每次验证之前建立一秒钟的延迟.
但是,我似乎无法正确中断已经运行的BackgroundWorker进程.
我的Visual Basic代码:
Sub W3CValidate(ByVal WholeDocumentText As String)
'stop any already-running validation
If ValidationWorker.IsBusy Then
ValidationWorker.CancelAsync()
'wait for it to become ready
While ValidationWorker.IsBusy
'pause for one-hundredth of a second
System.Threading.Thread.Sleep(New TimeSpan(0, 0, 0, 0, 10))
End While
End If
'start validation
Dim ValidationArgument As W3CValidator = New W3CValidator(WholeDocumentText)
ValidationWorker.RunWorkerAsync(ValidationArgument)
End Sub
看来在调用我的BackgroundWorker的CancelAsync()之后,它的IsBusy永远不会变为False.它陷入无限循环.
我究竟做错了什么?
我有一名背景工作者.在我调用worker之前,我禁用了一个按钮并使gif可见.然后我调用runworkerasync方法,它运行正常,直到comleteion.在'RunWorkerCompleted()'上我得到一个跨线程错误.知道为什么吗?
private void buttonRun_Click(object sender, EventArgs e)
{
if (comboBoxFiscalYear.SelectedIndex != -1 && !string.IsNullOrEmpty(textBoxFolderLoc.Text))
{
try
{
u = new UpdateDispositionReports(
Convert.ToInt32(comboBoxFiscalYear.SelectedItem.ToString())
, textBoxFolderLoc.Text
, Properties.Settings.Default.TemplatePath
, Properties.Settings.Default.ConnStr);
this.buttonRun.Enabled = false;
this.pictureBox1.Visible = true;
BackgroundWorker bw = new BackgroundWorker();
bw.DoWork += new DoWorkEventHandler(bw_DoWork);
bw.RunWorkerCompleted += new RunWorkerCompletedEventHandler(bw_RunWorkerCompleted);
bw.RunWorkerAsync();
//backgroundWorker1.RunWorkerAsync();
}
catch (Exception ex)
{
MessageBox.Show("Unable to process.\nError:" + ex.Message, Properties.Settings.Default.AppName);
}
}
}
void bw_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
{
buttonRun.Enabled = true;
pictureBox1.Visible = false;
}
void bw_DoWork(object sender, DoWorkEventArgs …Run Code Online (Sandbox Code Playgroud) 在WPF应用程序中,我使用BackgroundWorker定期检查服务器上的条件.虽然工作正常,但我希望弹出一个MessageBox,如果在检查过程中出现故障,请通知用户.
这就是我所拥有的:
public static void StartWorker()
{
worker = new BackgroundWorker();
worker.DoWork += DoSomeWork;
worker.RunWorkerAsync();
}
private static void DoSomeWork(object sender, DoWorkEventArgs e)
{
while (!worker.CancellationPending)
{
Thread.Sleep(5000);
var isOkay = CheckCondition();
if(!isOkay)
MessageBox.Show("I should block the main window");
}
}
Run Code Online (Sandbox Code Playgroud)
但是这个MessageBox不会阻塞主窗口.我仍然可以点击我的WPF应用程序并使用MessageBox更改我喜欢的任何内容.
我该如何解决这个问题?谢谢,
编辑:
作为参考,这是我最终做的事情:
public static void StartWorker()
{
worker = new BackgroundWorker();
worker.DoWork += DoSomeWork;
worker.ProgressChanged += ShowWarning;
worker.RunWorkerAsync();
}
private static void DoSomeWork(object sender, DoWorkEventArgs e)
{
while (!worker.CancellationPending)
{
Thread.Sleep(5000);
var isOkay = CheckCondition();
if(!isOkay)
worker.ReportProgress(1); …Run Code Online (Sandbox Code Playgroud) 当我的应用程序启动时,它刚刚升级,我正在进行本地数据库更新(sqlite).
它是这样的:用户启动我的应用程序,然后我开始升级过程.在此升级过程中,我将显示一个具有连续进度条的表单.升级过程完成后,此表单将关闭,然后用户可以开始使用我的应用程序.
但由于升级过程非常密集,因此进度条不会生成动画.
在我的旧版VB6中,我使用了一个ActiveX-Exe,它有一个表单并显示一个进度条.这是我的"背景工作者".
我不确定我是否可以在VB.NET中使用相同的方法.
我只看到了后台工作者的工作,但我没有看到任何示例,其中progressbar本身是后台工作者.
数据库升级需要阻止,用户可能在数据库升级完成之前不使用我的应用程序.这意味着只有进度条应该"进行中",而不是升级.
非常感谢你!
使用这两者来实现特定任务的利弊是什么.
百万美元的问题是哪一个使用什么时候?
非常感谢.
我有一个后台工作者基本上执行以下操作:
在有待处理的文件时,上述步骤需要循环并继续处理.
我希望后台工作者能够被停止,我看到了WorkerSupportsCancellation设置,但是如何确保它只能在文件之间停止,而不是在处理文件时?
我需要执行一个后台任务,其中包含一个显示完成百分比的进度条和一个取消按钮.除了任务细节之外,目前我只想得到一个实例,所以我只有三个主要的事件处理程序(DoWork,ProgressChanged和RunWorkerCompleted)和一个循环,只是增加一个计数器并在DoWork中休眠50ms.但是,除了最后一次之外它不会更新.
在Windows窗体中,我使用后台工作程序,它正常运行,没有任何问题.我想使用相同的代码.但是,我一直在看一些说ASP.NET必须使用AJAX来获得相同功能的东西.所以我的问题是:
1)我真的需要AJAX来使用后台工作者吗?
2)如果是的话,我确实需要AJAX,那些不了解AJAX的人可以做的最简单,最简单的方法是让后台工作者在ASP.NET网页上运行?
3)如果不是,我不需要AJAX,有人能指出我不使用它的工作样本吗?即使它使用其他线程方法而不是后台工作者,我感兴趣.
对不起多部分问题!如果你能回答其中一个,我们将不胜感激.我真的不介意我最终使用哪种方法,只要它有效.
代码来自.cs页面:
protected void bwProcess_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
{
lblProgress.Text = "Task Complete: " + e.Result;
}
protected void bwProcess_ProgressChanged(object sender, ProgressChangedEventArgs e)
{
lblProgress.Text = e.ProgressPercentage.ToString();
}
protected void bwProcess_DoWork(object sender, DoWorkEventArgs e)
{
for (int i = 0; i <= 100; i++)
{
if (bwProcess.CancellationPending)
{
lblProgress.Text = "Task Cancelled.";
e.Cancel = true;
return;
}
bwProcess.ReportProgress(i);
Thread.Sleep(50);
}
e.Result = "100%";
}
protected void BWClick(object sender, EventArgs e)
{ …Run Code Online (Sandbox Code Playgroud) 我目前正在编写一个简单的WPF 3.5应用程序,它利用SharePoint COM调用SharePoint站点并生成组和用户信息.由于此过程需要一段时间,因此我希望在生成组时显示ProgressBar.期望的过程如下:
我遇到的问题是UI永远不会更新.ProgressBar或ListView都不做任何更改.如果有人有任何想法来帮助下面的代码,将不胜感激.
private void GetGroupsAndUsersButton_Click(object sender, RoutedEventArgs e)
{
siteUrl = "";
if (SiteURLTextBox.Text.Length > 0)
{
FetchDataProgressBar.IsIndeterminate = true;
mWorker = new BackgroundWorker();
mWorker.DoWork += new DoWorkEventHandler(worker_DoWork);
mWorker.WorkerSupportsCancellation = true;
mWorker.RunWorkerCompleted += new RunWorkerCompletedEventHandler(worker_RunWorkerCompleted);
mWorker.RunWorkerAsync();
}
else
{
System.Windows.MessageBox.Show("Please enter a URL for the SharePoint site you wish to retrieve data");
}
}
private void worker_DoWork(object sender, System.ComponentModel.DoWorkEventArgs e)
{
siteUrl = SiteURLTextBox.Text;
GroupListView.ItemsSource = null;
try
{
using (SPSite site = new …Run Code Online (Sandbox Code Playgroud) 是否有任何共识是关于多线程应用程序的最佳实践:(1)使用单个,共享,静态连接到SQL数据库,或(2)每个BackgroundWorker打开它自己的唯一连接到数据库?
我显然假设每个线程都需要连接到同一个数据库.
使用类型是否会影响答案?例如,如果每个线程只运行SELECT语句怎么办?或者,如果某些线程也可以执行UPDATE语句?或者用法并没有真正有所作为,你应该总是/永远不分享静态连接?
backgroundworker ×10
c# ×7
wpf ×2
.net ×1
ajax ×1
asp.net ×1
asynchronous ×1
database ×1
messagebox ×1
progress-bar ×1
sharepoint ×1
vb.net ×1
vsto ×1
winforms ×1