我有一个在后台工作中运行的任务.单击开始按钮用户启动该过程并有一个取消按钮取消处理.
当用户点击取消时,我想显示一个消息框"进程尚未完成,是否要继续".
在这里,我希望只有在用户输入后才能进行处理.然后,然后想要停止背景线程.谁可以帮我这个事.反正有没有停止背景工作者一段时间.任何一种帮助将不胜感激.
是否有可能"杀死"一个线程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) 问题:重新使用.NET Backgroundworker,是不是有办法让异常正常传回主线程?
背景:
抛出没有异常,函数在此语句中暂停:
int productQuantity = Convert.ToInt32("1.00");
Run Code Online (Sandbox Code Playgroud)
并返回.
把这个浮点数转换成我做错了Int32什么?
注意:我正在运行BackgroundWorkerThread.
我正在将一个项目从winforms转移到WPF.当我的代码基于WinForms时,我使用(this.InvokeRequired)来检查线程是否具有访问权限.现在我使用基于Mainform的以下代码:
// this is the delegate declaration to Allow Background worker thread to write to Log Output
delegate void LogUpdateCallBack(String LogMessage);
// method to update the Log Window from the Background Thread
public void LogUpdate(String LogMessage)
{
Console.WriteLine("Entering");
if (!Application.Current.Dispatcher.CheckAccess())
{
Console.WriteLine("Thread doesn't have UI access");
LogUpdateCallBack callback = new LogUpdateCallBack(LogUpdate);
Application.Current.Dispatcher.Invoke(callback, LogMessage);
}
else
{
Console.WriteLine("Thread has UI access");
listBox_Output.Items.Add(LogMessage);
Console.WriteLine(LogMessage);
// listBox_Output.TopIndex = listBox_Output.Items.Count - 1;
}
Console.WriteLine("Exiting");
}
Run Code Online (Sandbox Code Playgroud)
我遇到的问题是Listbox没有更新.没有错误或异常,我尝试更新其他UI控件.LogMessage正在写入Output窗口,所以我很难过.
这是控制台输出的示例:
Entering
Thread doesn't have UI access
Entering …Run Code Online (Sandbox Code Playgroud) 我正在尝试创建一个ac#WinForms应用程序,用于搜索和突出显示RichTextBox中的文本.我创建了两种搜索方法:一种在GUI线程中运行,另一种在BackGroundWorker中运行.两种方法中的逻辑基本相同.但是,BGW中的代码运行速度要慢得多.
请看下面的结果:
搜索常用关键字的0.25MB文本文件:GUI:2.9s - BGW:7.0s
1MB搜索常用关键字的文本文件:GUI:14.1s - BGW:71.4s
5MB搜索常用关键字的文本文件:GUI:172s - BGW:1545s
我觉得奇怪的是,这两种方法所花费的时间之间的关系不是关于搜索大小的线性关系.
该应用程序将用于搜索最大10MB的文件,因此这很重要.我想使用后台工作程序,以便用户可以看到进度并在执行搜索时继续读取文件.
请参阅以下两种方法的代码:
// background search thread
private void backgroundWorker1_DoWork(object sender, DoWorkEventArgs e)
{
// Get the BackgroundWorker that raised this event.
BackgroundWorker worker = sender as BackgroundWorker;
RichTextBox rtb = new RichTextBox();
RichTextBox results = new RichTextBox();
rtb.Rtf = e.Argument as string; //recive text to be searched
int hits = 0; // track number of hits
int pos = 0; // track position in rtb
int i = …Run Code Online (Sandbox Code Playgroud) 我们绑定一个DataGridview使用BindingSource.所以在我们这样给出的主线程中.
class1BindingSource = new BindingSource();
class1BindingSource.DataSource = class1List;
this.dataGridView1.DataSource = class1BindingSource;
Run Code Online (Sandbox Code Playgroud)
之后,我在窗体中放置了一个后台工作器,并在单击按钮时触发.
即在按钮单击中
this.backgroundWorker1.RunWorkerAsync()
Run Code Online (Sandbox Code Playgroud)
在BackgroundWorker DoWork Event我试图BindingSource通过尝试更新来更新和那里DataGridview.
因此,BindingSource重置是在另一个类的方法中完成的.
DoWork Event
Class2 cl2 = new Class2();
cl2.UpdateBindingSource(class1BindingSource);
Run Code Online (Sandbox Code Playgroud)
UpdateBindingSource Method
public void UpdateBindingSource(BindingSource bs)
{
Class1 c1 = bs.Current as Class1;
for (int i = 0; i < 1000; i++)
{
lock (bs.SyncRoot)
{
c1.MyProperty1 = i;
bs.ResetItem(0);
}
}
}
Run Code Online (Sandbox Code Playgroud)
现在我得到一个例外,就像BindingSource它不能成为自己的数据源一样.不要将DataSource和DataMember属性设置为引用的值BindingSource. …
datagridview backgroundworker thread-safety bindingsource winforms
问题的名称是:" 从后台工作者更新GUI ",但正确的名称世界是:" 从后台工作者更新GUI或从后台工作者报告多个变量(除了整数) "
请让我解释一下我的情况.在一个程序中,我有一个后台工作者来分析信息.作为这种分析的结果 - 形式GUI元素应该填充必要的数据.在GUI中我想更新
据我所知 - 我只能通过后台工作者的方法本地报告1个int值ReportProgress().
所以问题是 - 我怎样才能传递List<>(+一些其他变量:string,int)ReportProgress()?基本上 - 我想用信息更新GUI,但是"1整数"不会这样做.所以要么可以通过ReportProgress()OR 传递多个变量, 我可以使用InvokeBackgroundWorker内部的一个来更新GUI.我个人不喜欢这个Invoke方法...你有什么看法?
这是我的代码(见评论):
private void button9_Click(object sender, EventArgs e) // start BW
{
bw.DoWork += new DoWorkEventHandler(backgroundWorker1_DoWork);
bw.RunWorkerCompleted += new RunWorkerCompletedEventHandler(backgroundWorker1_RunWorkerCompleted);
bw.ProgressChanged += new ProgressChangedEventHandler(backgroundWorker1_ProgressChanged);
bw.WorkerReportsProgress = true;
bw.WorkerSupportsCancellation = true;
bw.RunWorkerAsync(10);
}
private void button10_Click(object sender, EventArgs e) // cancel …Run Code Online (Sandbox Code Playgroud) 我有一个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
winforms ×4
.net ×3
wpf ×2
datagridview ×1
dispatcher ×1
int32 ×1
logic ×1
math ×1
performance ×1
progress-bar ×1