C#多线程异步文件操作

1.多线程的实现方式

        1.1Thread实现

using System.Threading;

class SimpleThreadExample {
    static void ThreadWork() {
        for(int i = 0; i < 10; i++) {
            Console.WriteLine($"Thread work: {i}");
            Thread.Sleep(1000); // 模拟耗时操作
        }
    }

    public static void Main() {
        Thread t = new Thread(new ThreadStart(ThreadWork));
        t.Start(); // 启动线程
        Console.WriteLine("Main thread work...");
    }
}

        1.2Task实现

using System.Threading.Tasks;

class TPLExample {
    static void DoWork(int value) {
        for(int i = 0; i < 10; i++) {
            Console.WriteLine($"Task work: {value} - {i}");
            Task.Delay(100).Wait(); // 模拟耗时操作
        }
    }

    public static void Main() {
        Task t1 = Task.Run(() => DoWork(1));
        Task t2 = Task.Run(() => DoWork(2));
        
        Task.WaitAll(t1, t2); // 等待所有任务完成
        Console.WriteLine("Main completed.");
    }
}

        1.3并行数据处理

using System.Threading.Tasks;
using System.Linq;

class ParallelForEachExample {
    public static void Main() {
        var numbers = Enumerable.Range(0, 100).ToArray();
        
        Parallel.ForEach(numbers, number => {
            Console.WriteLine($"Processing number: {number}");
            // 执行操作
        });
        Console.WriteLine("Done processing all numbers.");
    }
}

        1.4线程安全

private object _lock = new object();

...
lock(_lock) {
    // 执行临界区代码
}

2.文件操作

        2.1写入文件

        简单写入:

public async Task SimpleWriteAsync()
{
    string filePath = "simple.txt";
    string text = $"Hello World";

    await File.WriteAllTextAsync(filePath, text);
}

        有限控制示例:

public async Task ProcessWriteAsync()
{
    string filePath = "temp.txt";
    string text = $"Hello World{Environment.NewLine}";

    await WriteTextAsync(filePath, text);
}

async Task WriteTextAsync(string filePath, string text)
{
    byte[] encodedText = Encoding.Unicode.GetBytes(text);

    using var sourceStream =
        new FileStream(
            filePath,
            FileMode.Create, FileAccess.Write, FileShare.None,
            bufferSize: 4096, useAsync: true);

    await sourceStream.WriteAsync(encodedText, 0, encodedText.Length);
}

        2.2读取文件

        简单读取:

public async Task SimpleReadAsync()
{
    string filePath = "simple.txt";
    string text = await File.ReadAllTextAsync(filePath);

    Console.WriteLine(text);
}

        有限控制示例:

public async Task ProcessReadAsync()
{
    try
    {
        string filePath = "temp.txt";
        if (File.Exists(filePath) != false)
        {
            string text = await ReadTextAsync(filePath);
            Console.WriteLine(text);
        }
        else
        {
            Console.WriteLine($"file not found: {filePath}");
        }
    }
    catch (Exception ex)
    {
        Console.WriteLine(ex.Message);
    }
}

async Task<string> ReadTextAsync(string filePath)
{
    using var sourceStream =
        new FileStream(
            filePath,
            FileMode.Open, FileAccess.Read, FileShare.Read,
            bufferSize: 4096, useAsync: true);

    var sb = new StringBuilder();

    byte[] buffer = new byte[0x1000];
    int numRead;
    while ((numRead = await sourceStream.ReadAsync(buffer, 0, buffer.Length)) != 0)
    {
        string text = Encoding.Unicode.GetString(buffer, 0, numRead);
        sb.Append(text);
    }

    return sb.ToString();
}

3.并发文件操作

        3.1 同时创建多个文件

        简单示例:

public async Task SimpleParallelWriteAsync()
{
    string folder = Directory.CreateDirectory("tempfolder").Name;
    IList<Task> writeTaskList = new List<Task>();

    for (int index = 11; index <= 20; ++ index)
    {
        string fileName = $"file-{index:00}.txt";
        string filePath = $"{folder}/{fileName}";
        string text = $"In file {index}{Environment.NewLine}";

        writeTaskList.Add(File.WriteAllTextAsync(filePath, text));
    }

    await Task.WhenAll(writeTaskList);
}

        有限控制示例:

        该示例将在任务完成后关闭 finally 块中的所有 FileStream 实例。 如果每个 FileStream 均已在 using 语句中创建,则可能在任务完成前释放 FileStream

public async Task ProcessMultipleWritesAsync()
{
    IList<FileStream> sourceStreams = new List<FileStream>();

    try
    {
        string folder = Directory.CreateDirectory("tempfolder").Name;
        IList<Task> writeTaskList = new List<Task>();

        for (int index = 1; index <= 10; ++ index)
        {
            string fileName = $"file-{index:00}.txt";
            string filePath = $"{folder}/{fileName}";

            string text = $"In file {index}{Environment.NewLine}";
            byte[] encodedText = Encoding.Unicode.GetBytes(text);

            var sourceStream =
                new FileStream(
                    filePath,
                    FileMode.Create, FileAccess.Write, FileShare.None,
                    bufferSize: 4096, useAsync: true);

            Task writeTask = sourceStream.WriteAsync(encodedText, 0, encodedText.Length);
            sourceStreams.Add(sourceStream);

            writeTaskList.Add(writeTask);
        }

        await Task.WhenAll(writeTaskList);
    }
    finally
    {
        foreach (FileStream sourceStream in sourceStreams)
        {
            sourceStream.Close();
        }
    }
}


 引用如下,如有侵权立即删除:https://learn.microsoft.com/zh-cn/dotnet/csharp/asynchronous-programming/using-async-for-file-accessicon-default.png?t=N7T8https://learn.microsoft.com/zh-cn/dotnet/csharp/asynchronous-programming/using-async-for-file-access

                

              

  • 3
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
C#中,可以使用多线程来实现异步加载。一种常见的方法是使用Thread类创建子线程,并在子线程中执行需要异步加载的任务。可以通过ThreadStart委托将要执行的方法与新线程对象关联起来。例如,在FrmQC111_Load方法中,可以创建一个新的线程load,并将loadpage方法与该线程关联起来。loadpage方法中使用Action委托与具体的方法Bindt进行绑定,并使用BeginInvoke方法进行异步调用。Bindt方法用于实现加载控件数据源的操作。[1] 另一种常见的方法是使用Task类来执行异步任务。在.NET 4.0及以上版本中,可以使用Task类来实现异步操作。Task类提供了一种更方便的方式来执行异步任务,并且可以提高程序的运行效率。在.NET 5.0中,还引入了async/await关键字,使得异步编程更加方便。[2] 下面是两种方法的示例代码: 使用Thread类: ```csharp private void FrmQC111_Load(object sender, EventArgs e) { Thread load = new Thread(new ThreadStart(loadpage)); load.Start(); } private void loadpage() { // 执行异步加载的操作 Bindt(); } private void Bindt() { // 实现具体的加载操作 // ... } ``` 使用Task类: ```csharp private async void FrmQC111_Load(object sender, EventArgs e) { await Task.Run(() => Bindt()); } private void Bindt() { // 实现具体的加载操作 // ... } ``` 以上是两种常见的在C#中实现多线程异步加载的方法。具体选择哪种方法取决于你的需求和编程习惯。[3]

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值