2009-03-24 19 views
3

ファイルを保存できる必要があります。残念ながら、ファイルが潜在的に非常に大きいため、保存に数分かかる可能性があります。 GUIスレッドからこれを行う必要があるため、GUIの実行をブロックしたくありません。私は、プライマリGUIスレッドが実行を継続できるように別のスレッドでセーブ操作を試みることを考えていました。ファイル操作のためのC#スレッド

新しいスレッドを作成し、ファイルを保存し、スレッドを破壊するための良い(簡単な)方法はありますか?

私は完全な初心者ですので、私は決して前にスレッドを使用していたと言わなければなりません!すべての助けが大いに評価されるでしょう!

答えて

5

BackgroundWorker(Frederikの提案通り)は、特に保存中にUIに進捗状況を報告したい場合に適しています。 search for BackgroundWorker tutorialはヒット数が多いので、開始するにはそのうちの1つに従うことができます。

注意すべき点:UIスレッドから保存しようとしているデータ構造を変更する方法はありますか?その場合は、保存中にUIのこれらの要素を無効にする必要があります。データを保存する途中になって、ユーザーが一部を変更できるようにするのは悪いことでしょう(おそらく!)。バックグラウンドスレッドにデータを効果的に渡してからUIスレッドに触れないようにすれば、それはあなたの人生を楽にします。

+0

私は、データのコピーを作成し、UIの一部を無効にするのではなく、バックグラウンドワーカーにそれを渡す方が良いと思います。 – Quibblesome

+0

@Quarrelome:時には。それは実際の状況と、結果がスナップショットになるかどうかをユーザーが期待するかどうかによって異なります。また、いくつかのケースでは、完全なスナップショットを取ることは本当に難しいかもしれません - それは壊れたものよりも信頼できるが少し迷惑なプログラムを持っている方が良いです:) –

5

おそらくBackGroundWorkerコンポーネントを使用することができます。これは、スレッド化部分を少し抽象化するためです。

3

あなたの問題には、いくつかの簡単で簡単な方法があるかもしれません。あなただけオフに設定したい場合は、ファイルを保存し、それが完了したときにメソッド

void SaveMyFile(object state) 
{ 
    // SaveTheFile 
} 

を持って、あなたがやりたいだろう

ThreadPool.QueueUserWorkItem(SaveMyFile); 

でそれを呼び出して、知って心配しないで。

0

または旧友の代理人を使用できます。

3

非同期I/Oをお勧めします。セットアップが少し簡単で、新しいスレッドを自分で作成する必要はありません。

非同期プログラミングでは、たとえば書き込みたいファイルストリームがありますが、終了するまで待機したくない場所です。あなたは完了したときに通知を受けることを望むかもしれませんが、あなたは待っていません。

何をしてStreamクラスに用意されていBeginWrite/BeginReadEndWrite/EndReadの機能を使用しています。

あなたのメソッドでは、BeginWriteを書いて、コールバック関数で渡すすべてのデータを呼び出すことから始めます。この関数は、BeginWriteが終了したときに呼び出されます。

コールバック関数では、EndWriteを呼び出してストリームをクリーンアップし、エラーをチェックします。

BeginWriteはブロックされません。これは、スレッドがそのハンドラを終了し、他のイベント(他のGUIイベントなど)を処理し続けるイベントハンドラ内から呼び出された場合に発生します。メインスレッドが殺された場合のものを書くのスレッドが殺されるので

using System; 
using System.IO; 
using System.Text; 

class Program 
    { 
     private static FileStream stream; 
     static void Main(string[] args) 
     { 
      stream = new FileStream("foo.txt", 
            FileMode.Create, 
            FileAccess.Write); 

      const string mystring = "Foobarlalala"; 
      ASCIIEncoding encoding = new ASCIIEncoding(); 
      byte[] data = encoding.GetBytes(mystring); 
      Console.WriteLine("Started writing"); 
      stream.BeginWrite(data, 0, data.Length, callback, null); 
      Console.WriteLine("Writing dispatched, sleeping 5 secs"); 
      System.Threading.Thread.Sleep(5000); 
     } 

     public static void callback(IAsyncResult ia) 
     { 
      stream.EndWrite(ia); 
      Console.WriteLine("Finished writing"); 
     } 
    } 
} 

睡眠はとても重要です。この小さな例では、GUIアプリケーションでは問題ありません。

MSDNあなたはbackgroundworkerThreadPoolのために行く場合には、一般的に非同期プログラミングにこのようなものを書く方法についてpretty good overviewを持っており、またいくつかのgood articles

関連する問題