用于文件操作的C#线程

时间:2009-03-24 09:55:47

标签: c# multithreading io

我必须能够保存文件,不幸的是它可能会非常大,因此保存它可能需要几分钟。因为我需要从GUI线程执行此操作,所以我不想阻止GUI执行。我正在考虑在单独的线程上尝试保存操作,以允许主GUI线程继续执行。

是否有一种很好的(简单)方法来生成一个新线程,保存文件,并破坏线程而没有任何令人讨厌的副作用?!

必须说我从来没有必须使用线程所以我是一个完整的新手!任何和所有的帮助将不胜感激!

5 个答案:

答案 0 :(得分:5)

你可以使用BackGroundWorker组件,因为它会为你抽象一些线程部分。

答案 1 :(得分:5)

BackgroundWorker(由Frederik建议)是一个不错的选择,特别是如果您想在保存时向UI报告进度。 search for BackgroundWorker tutorial获得了很多点击量,所以你应该能够按照其中一个来开始。

有一点需要注意:是否有任何方法可以更改您尝试从UI线程保存的数据结构?如果是这样,您应该在保存时禁用UI的这些方面 - 它可能(可能!)在保存数据的一半时间不好,然后允许用户更改其中的一部分。如果你能够有效地将数据传递给后台线程,然后不从UI线程中触摸它,那将使你的生活变得更加轻松。

答案 2 :(得分:3)

您的问题可能是有几种简单易行的方法。如果你只是想要设置文件保存而不用担心知道它何时完成,那么就有一个方法

void SaveMyFile(object state)
{
    // SaveTheFile
}

并用

调用它
ThreadPool.QueueUserWorkItem( SaveMyFile );

会做你想做的事。

答案 3 :(得分: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应用程序中的问题,仅在此小例子中。

如果您选择pretty good overviewgood articles,MSDN在编写此内容时会有backgroundworker,并且在Asynch编程上也会有一些ThreadPool。< / p>

答案 4 :(得分:0)

或者你可以使用老朋友代表。