2012-05-03 8 views
0

Form1でこの機能を使用していましたが、大きなXMLファイルからテキストを取得するのが良いと思いました。だから、Form1の構築で私はした:クラスメソッドがBackgroundWorkerで実行されているときに、別のフォームでクラスを再利用するにはどうすればよいですか?

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

新しいクラスでは、いくつかの変数を取得する新しい関数public関数を作成しました。 m 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) 
     { 

私の問題は、変更すると、それはまた、仕事とbackgroundworker2で使用しますので、新しい機能へのForm1から新しいクラスにテスト()関数を変換する方法ですか?

私は、そこにFileStreamを追加/追加しようとしましたが、行ごとに読み込まれるwhieループが追加されましたが、うまくいきませんでした。

**これは、Form1の中で)、それはテスト(あったようにdosent行為がWICH機能を持つ新しいクラスです**

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変数です Form1のコンストラクタでfを使用して大きなxmlファイルを読み込んでいますが、新しいクラスでもFileStreamを使用しています。 **

+0

あなたが望むように切り離されています。バックグラウンドワーカーはクラスインスタンスです。どこにでも定義できます。 Filestreamオブジェクトは同じです。アプリケーション内で(お互いに)見える限り、呼び出す場所には何の違いもありません(パブリック)。だから、あなたが「それはうまくいきませんでした」と言ったとき、まさに問題でしたか?私はそれがbackgroundworker2を使用せず、唯一のForm1にいたとき、私はそれが動作するように望んでいたとして、それが働いていたことを私は意味、「それは良い仕事didntの」と言っ –

+0

。しかし、私が新しいクラスに移動するとすぐに、私はそれを望んでいないモエの文字列を抽出しました。つまり、xmlのテキストだけでなく、より多くのタグを抽出したということです。そして、文字列変数を使用して、関数イムの新しいクラスでウィッヒを読んForm1の中とForm1の列FのF文字列が最後に大きなxmlファイルを読んでいるが、新しいクラスと機能イムでものFileStreamウィッヒを使用しても、これを読んでいるありますビッグXMLファイル。その後、私は新しいクラスの変数を混合しました。 – user1363119

+0

新しいクラスにあるので、関数とコードを自分の投稿に追加します。それは私にエラーを与えていないが、私が必要とするようにdosent仕事。 – user1363119

答えて

0

あなたのプログラミングの考え方を少し変えることが役に立ちます。フォームやイベントを考えるのではなく、データエンティティとそのデータエンティティのアクションを考えると、サービスタイプパターンを使用できます。

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

public class FileWorkerService 
{ 
    private BackgroundWorker _worker; 

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

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

これで、あなたのイベントで以前と同じ方法で作業を行い、サービスクラスが作業準備が整いました。

何かを実行するには、そのインスタンスを作成し、ワーカーを開始する関数を呼び出すだけです。

あなたのフォームのボタンをクリックするとあなたは持っているでしょう...

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

================= EDIT =================== =============== - サービス内からバックグラウンドワーカーの進行状況を更新する方法を追加しました。 < < < ============================================== ============あなたのメインフォームから、クラスの外に呼び出すためにあなたのFileWorkerServiceクラス

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

インサイド

、あなたはどうしたら...これらの事のすべてのようにすることができ

newService.SetWorkerProgress(whatever); 
+0

Davidそして、私はbackgroundworkerを扱うためにtest()関数をどのように変更/使用しますか? Form1のようにtest()関数で何も変更しないでくださいが、backgroundWorker2.ReportProgress(パーセント)のような変数からbackgroundworkerに渡す必要があります。私は前にFileStreamと一緒に使っていましたが、test()関数で何も変更したくないと言うと、どうやってbackgroundworkerに報告できますか? – user1363119

+0

作成したサービスクラスにバックグラウンドワーカーが属しているため、サービスクラスがコンジットになります。あなたはサービス・クラスにバックグラウンド・ワーカーを直接触れることができるようにアクセサを作成することも、バックグラウンド・ワーカーにしたいことをするメソッドを作成することもできます。私は本当に、私は –

+0

はあなたがトラブルあなたはそれが何をしたい、またはあなたがフォームに戻って、その値を報告するサービスワーカーを得るトラブルを抱えているものを行うためにサービスワーカーの取得を行っている主要なポストを編集しますここでコンテンツをフォーマットすることはできませんジョブ全体が処理される前に、それを表示するには、(多くの場合、問題が長期実行中のプロセスやリサイズを扱うときに)私はテストに意味 –

関連する問題