C# 在BackgroundWorker中运行类方法时,如何以不同的形式重用类?
我在Form1中有这个函数,它运行得很好。这个想法是从一个大的xml文件中检索一些文本。所以在Form1结构中,我做了:C# 在BackgroundWorker中运行类方法时,如何以不同的形式重用类?,c#,backgroundworker,C#,Backgroundworker,我在Form1中有这个函数,它运行得很好。这个想法是从一个大的xml文件中检索一些文本。所以在Form1结构中,我做了: r = new StreamReader(@"D:\Deponia_Work\Deponia Extracted Files\000004aa.xml"); f = r.ReadToEnd(); r.Close(); 变量f是字符串 现在,我在Form1中有一个名为test()的函数,它从大的000004aa.xml文件中检索/提取文本 private
r = new StreamReader(@"D:\Deponia_Work\Deponia Extracted Files\000004aa.xml");
f = r.ReadToEnd();
r.Close();
变量f是字符串
现在,我在Form1中有一个名为test()的函数,它从大的000004aa.xml文件中检索/提取文本
private void test()
{
int countFiles = 0;
byte[] a;
string startTag = "T256=\"";
string endTag = "\"";
int index = 0;
int startTagWidth = startTag.Length;
int endTagWidth = endTag.Length;
int fileLength = f.Length;
w = new StreamWriter(@"d:\testingdeponias.txt");
while (true)
{
if (index > f.LastIndexOf(startTag))
{
break;
}
int startTagIndex = f.IndexOf(startTag, index);
int stringIndex = startTagIndex + startTagWidth;
index = stringIndex;
int endTagIndex = f.IndexOf(endTag, index);
int stringLength = endTagIndex - stringIndex;
if (stringLength == 0)
{
}
else
{
string test = f.Substring(stringIndex, stringLength);
if (test.Contains("<pa>"))
{
string t = "<pa>";
int y = t.Length;
string test1 = test.Substring(0, stringLength - y);
listBox1.Items.Add(test1);
w.WriteLine(test1);
}
//else
// {
listBox1.Items.Add(test);
w.WriteLine(test);
// }
}
}
w.Close();
}
然后我在Form1中添加了一个新的BackgroundWorker2事件:
这是道工活动:
private void backgroundWorker2_DoWork(object sender, DoWorkEventArgs e)
{
BackgroundWorker worker2 = sender as BackgroundWorker;
lists1.extractTextDeponia(worker2, backgroundWorker2, listBox1, textBox1,f, w, e);
}
这是启动backgroundworker的按钮单击事件:
private void button8_Click(object sender, EventArgs e)
{
backgroundWorker2.RunWorkerAsync();
}
在新类中,我创建了一个新函数public function,它从Form1中获取一些变量
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.IO;
using System.Web;
using System.Text.RegularExpressions;
using System.Xml;
using System.Xml.Linq;
namespace List_Words
{
class Lists
{
public void List_Words()
{
}
public void extractTextDeponia(BackgroundWorker worker, BackgroundWorker backgroundWorker2, ListBox lbox , TextBox tbox , StreamWriter streamW , string read, DoWorkEventArgs e)
{
我的问题是如何更改test()函数,并将其从Form1转换为新类,再转换为新函数,以便它也能与backgroundworker2一起工作和使用
我尝试在那里使用/addfilestream并添加while循环,它将逐行读取,但效果不好
**这是一个新类,其中的函数与Form1中的test()不同**
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.IO;
using System.Web;
using System.Text.RegularExpressions;
using System.Xml;
using System.Xml.Linq;
namespace List_Words
{
class Lists
{
public void List_Words()
{
}
public void extractTextDeponia(BackgroundWorker worker, BackgroundWorker backgroundWorker2, ListBox lbox , TextBox tbox , StreamWriter streamW , string read, DoWorkEventArgs e)
{
string startTag = "T256=\"";
string endTag = "\"";
int index = 0;
int startTagWidth = startTag.Length;
int endTagWidth = endTag.Length;
int fileLength = read.Length;
using (var fs = new FileStream(@"D:\Deponia_Work\Deponia Extracted Files\000004aa.xml", FileMode.Open, FileAccess.Read))
{
using (var h = new StreamReader(fs))
{
string line;
line = h.ReadLine();
while ((line = h.ReadLine()) != null)
{
if (worker.CancellationPending == true)
{
e.Cancel = true;
break;
}
else
{
int percent = (int)(fs.Position * 100 / fs.Length);
backgroundWorker2.ReportProgress(percent);
if (index > read.LastIndexOf(startTag))
{
break;
}
int startTagIndex = read.IndexOf(startTag, index);
int stringIndex = startTagIndex + startTagWidth;
index = stringIndex;
int endTagIndex = read.IndexOf(endTag, index);
int stringLength = endTagIndex - stringIndex;
if (stringLength == 0)
{
}
else
{
line = read.Substring(stringIndex, stringLength);
if (line.Contains("<pa>"))
{
string t = "<pa>";
int y = t.Length;
string test1 = line.Substring(0, stringLength - y);
if (lbox.InvokeRequired)
{
lbox.Invoke(new MethodInvoker(delegate { lbox.Items.Add(test1); }));
}
//w.WriteLine(test1);
line = h.ReadLine();
if (tbox.InvokeRequired)
{
tbox.Invoke(new MethodInvoker(delegate { tbox.Text = test1; }));
}
}
//else
// {
if (lbox.InvokeRequired)
{
lbox.Invoke(new MethodInvoker(delegate { lbox.Items.Add(line); }));
}
//w.WriteLine(line);
if (tbox.InvokeRequired)
{
tbox.Invoke(new MethodInvoker(delegate { tbox.Text = line; }));
}
// }
}
}
}
}
}
streamW = new StreamWriter(@"d:\testingdeponias.txt");
streamW.AutoFlush = true;
streamW.Write(read);
streamW.Close();
}
}
}
在表格1中,我称之为:
BackgroundWorker worker2 = sender as BackgroundWorker;
lists1.extractTextDeponia(worker2, backgroundWorker2, listBox1, textBox1,w, f, e);
w是流编写器f是字符串,e是backgroundowrker2 DoWork e变量
如上所示,我在Form1构造函数中使用f来读取大的xml文件,但我也在新的类和函数中使用FileStream来读取,真是一团糟** 有一件事可能会有所帮助,那就是稍微改变一下你的编程思维。不要考虑表单和事件,而是考虑数据实体和这些数据实体上的操作,然后您可以使用服务类型模式 所以,您要做的是创建一个服务类,它执行您希望执行的任何操作。因为您使用的是后台工作程序,所以我将把它创建为一个实例类,而不是静态类
public class FileWorkerService
{
private BackgroundWorker _worker;
public FileWorkerService()
{
_worker = new BackgroundWorker();
}
public void ReadFileAndProcessIt()
{
if (!_worker.IsBusy)
{
_worker.RunWorkerAsync();
}
}
}
现在,只需像您之前使用事件一样连接_worker,您的服务类就可以开始工作了
为了让它做一些事情,您只需创建它的一个实例并调用启动worker的函数
所以在你的表单按钮上点击你会
private void button8_Click(object sender, EventArgs e)
{
var newService = new FileWorkerService();
newService.ReadFileAndProcessIt();
}
=========================编辑==================================
--添加了如何从服务中更新后台工作人员的进度。
所有这些东西都可以像你想要的那样解耦。后台工作程序是一个类实例,您可以在任何地方定义它。Filestream对象是相同的。只要它们可以从应用程序(public)中看到彼此,那么在何处调用它们就没有什么区别。那么,当你说“它不好用”时,到底是什么问题呢?当我说“它不好用”时,我的意思是,当它只在Form1中,而没有使用backgroundworker2时,它正按照我希望的方式工作。但是,当我把它转移到新的类中时,它就提取了我不想要的moew字符串。我的意思是它从xml中提取了更多的标记,而不仅仅是文本。在函数的新类中,im使用变量string read,在Form1中,它是string f,在Form1中,string f一直在读取大xml文件,但在新类和函数中,im也使用FileStream,它也在读取这个大xml文件。然后我在新类中混合了变量。我将在帖子中添加新类中的函数和代码。它不会给我错误,但它不会像我需要的那样工作。好吧,当你发布一个问题时,你需要详细说明你的问题是什么(特别是如果有错误代码的话)。这将避免像我这样的人花时间试图找出你想要的东西和编写你不需要的解决方案。David,我如何更改/使用test()函数与backgroundworker一起工作?假设我没有改变test()函数中的任何内容,因为它在Form1中,但我需要以某种方式将变量传递给backgroundworker,例如backgroundWorker2.ReportProgress(百分比);我以前在FileStream中使用过它,但是假设我不想更改test()函数中的任何内容。我如何向backgroundworker报告?因为后台工作程序属于您创建的服务类,所以您的服务类将成为管道。您可以创建一个访问器,以便直接将后台工作程序连接到您的服务类,也可以创建一个对后台工作程序执行所需操作的方法。我无法在此处格式化内容,因此我将编辑主邮件。您是否无法让服务人员执行您希望它执行的操作,或者您是否无法让服务人员将其值报告回表单并在处理整个作业之前显示它(处理长时间运行的进程和winforms时经常出现问题)David我是说在test()函数中,如何计算要报告的百分比?我以前使用过FileStream,并且使用了int percent=(int)(fs.Position*100/fs.Length);backgroundWorker2.ReportProgress(percent);但是,如果我没有像使用test()函数一样使用FileStream,那么如上所述,我如何计算进度,以便向backgroundworker报告进度。我现在的问题是向BackgoundWorker报告的计算。
public void SetWorkerProgress(int currentValue)
{
_worker.ReportProgress(currentValue);
}
newService.SetWorkerProgress(whatever);