-1

Form1 にこの機能があり、うまく機能しました。アイデアは、大きな xml ファイルからテキストを取得することでした。したがって、Form1 の構築では、次のようにしました。

r = new StreamReader(@"D:\Deponia_Work\Deponia Extracted Files\000004aa.xml");
f = r.ReadToEnd();
r.Close();

変数 f は文字列です。

Form1 には、大きな 000004aa.xml ファイルからテキストを取得/抽出する test() という関数がありました。

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 に新しい backgroudnworker2 イベントを追加しました。

これは DoWork イベントです:

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();
        }

新しいクラスでは、Form1 からいくつかの変数を取得する新しい関数 public 関数を作成しました。

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 でも機能して使用できるようになりますか?

そこに FileStream を使用/追加しようとし、行ごとに読み取る 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();
        }


    }
}

そして、form1 では次のように呼んでいます:

BackgroundWorker worker2 = sender as BackgroundWorker;
lists1.extractTextDeponia(worker2, backgroundWorker2, listBox1, textBox1,w, f, e);

w はストリーム ライター f は文字列、e は backgroundowrker2 DoWork e 変数 上記で示したように、Form1 コンストラクターで f を使用して大きな xml ファイルを読み取っていますが、新しいクラスでもそれを実行し、FileStream を使用して機能します。**

4

1 に答える 1

0

役立つかもしれない1つのことは、プログラミングの考え方を少し変えることです。フォームとイベントを考える代わりに、それらのデータエンティティのデータエンティティとアクションを考えてから、サービスタイプパターンを使用できます。

つまり、あなたがすることは、あなたがしたいことを何でもするサービスクラスを作成することです。バックグラウンドワーカーを使用しているので、静的ではなくインスタンスクラスとして作成します。

public class FileWorkerService
{
   private BackgroundWorker _worker;

   public FileWorkerService()
    {
       _worker = new BackgroundWorker();
    }

   public void ReadFileAndProcessIt()
    {
      if (!_worker.IsBusy)
        {
          _worker.RunWorkerAsync();
        }
    } 
 }

これで、以前と同じように_workerをイベントに接続するだけで、サービスクラスで作業を行う準備が整います。

何かを実行させるには、インスタンスを作成し、ワーカーを起動する関数を呼び出すだけです。

したがって、フォームボタンをクリックすると...

private void button8_Click(object sender, EventArgs e)
        {
            var newService = new FileWorkerService();
            newService.ReadFileAndProcessIt();
        }

=================編集================================ ==-サービス内からバックグラウンドワーカーの進行状況を更新する方法を追加しました。<<< =============================================== ===========

FileWorkerServiceクラス内

public void SetWorkerProgress(int currentValue)
{
   _worker.ReportProgress(currentValue);
}

クラスの外で、メインフォームから電話をかけるには、次のようにします...

newService.SetWorkerProgress(whatever);
于 2012-05-03T18:52:14.330 に答える