异步写入文件

CPK*_*011 24 c# asp.net asynchronous

有没有办法编写一个异步函数,可以重复地将数据写入文件.

我写异步函数时收到以下错误

该进程无法访问文件'c:\ Temp\Data.txt',因为它正由另一个进程使用

public void GoButton_Click(object sender, System.EventArgs e)
{
    IAsyncResult ar = DoSomethingAsync(strURL, strInput);
    Session["result"] = ar;
    Response.Redirect("wait1.aspx");
}

private IAsyncResult DoSomethingAsync(string strURL, string strInput)
{
    DoSomethingDelegate doSomethingDelegate = new DoSomethingDelegate(DoSomething);
    IAsyncResult ar = doSomethingDelegate.BeginInvoke(strURL, strInput, new AsyncCallback(MyCallback), null);
    return ar;
}

private delegate void DoSomethingDelegate(string strURL, string strInput);

private void MyCallback(IAsyncResult ar)
{
    AsyncResult aResult = (AsyncResult)ar;
    DoSomethingDelegate doSomethingDelegate = (DoSomethingDelegate)aResult.AsyncDelegate;
    doSomethingDelegate.EndInvoke(ar);
}

private void DoSomething(string strURL, string strInput)
{
    int i = 0;
    for (i = 0; i < 1000; i++)
    {
        m_streamWriter.BaseStream.Seek(0, SeekOrigin.End); 
        m_streamWriter.WriteLine("{0} ", MethodCall(strURL, strInput));
        m_streamWriter.Flush();
        m_streamWriter.Close();
    }
}
Run Code Online (Sandbox Code Playgroud)

cur*_*Boy 24

我有同样的问题.现在就解决了.这是一种迟到的建议,但可能对其他人有所帮助.

在下面的控制台示例中包含以下using语句.

using System;
using System.Collections.Generic;
using System.IO;
using System.Text;
using System.Threading.Tasks;
Use of the FileStream Class
Run Code Online (Sandbox Code Playgroud)

下面的示例使用FileStream类,该类具有导致在操作系统级别发生异步I/O的选项.在许多情况下,这将避免阻塞ThreadPool线程.要启用此选项,必须在构造函数调用中指定useAsync = true或options = FileOptions.Asynchronous参数.

如果通过指定文件路径直接打开StreamReader和StreamWriter,则它们没有此选项.如果您为它们提供由FileStream类打开的Stream,StreamReader/Writer确实有此选项.请注意,即使线程池线程被阻止,异步也会在UI应用程序中提供响应性优势,因为在等待期间不会阻止UI线程.

写文字

以下示例将文本写入文件.在每个await语句中,该方法立即退出.文件I/O完成后,该方法将在await语句后面的语句处继续.请注意,async修饰符位于使用await语句的方法的定义中.

static void Main(string[] args)
{
    ProcessWrite().Wait();
    Console.Write("Done ");
    Console.ReadKey();
}

static Task ProcessWrite()
{
    string filePath = @"c:\temp2\temp2.txt";
    string text = "Hello World\r\n";

    return WriteTextAsync(filePath, text);
}

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

    using (FileStream sourceStream = new FileStream(filePath,
        FileMode.Append, FileAccess.Write, FileShare.None,
        bufferSize: 4096, useAsync: true))
    {
        await sourceStream.WriteAsync(encodedText, 0, encodedText.Length);
    };
}
Run Code Online (Sandbox Code Playgroud)

阅读文字

以下示例从文件中读取文本.文本是缓冲的,在这种情况下,放在StringBuilder中.与前面的示例不同,await的评估会产生一个值.ReadAsync方法返回一个Task,因此await的评估会产生一个Int32值(numRead),该值在操作完成后返回.

static void Main(string[] args)
{
    ProcessRead().Wait();
    Console.Write("Done ");
    Console.ReadKey();
}

static async Task ProcessRead()
{
    string filePath = @"c:\temp2\temp2.txt";

    if (File.Exists(filePath) == false)
    {
        Console.WriteLine("file not found: " + filePath);
    }
    else {
        try {
            string text = await ReadTextAsync(filePath);
            Console.WriteLine(text);
        }
        catch (Exception ex)
        {
            Console.WriteLine(ex.Message);
        }
    }
}

static async Task<string> ReadTextAsync(string filePath)
{
    using (FileStream sourceStream = new FileStream(filePath,
        FileMode.Open, FileAccess.Read, FileShare.Read,
        bufferSize: 4096, useAsync: true))
    {
        StringBuilder 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();
    }
} 
Run Code Online (Sandbox Code Playgroud)

您可以从使用Async for File Access查看原始来源

希望有帮助......

  • 答案现在有解决方案. (3认同)

Ste*_*veD 9

处理异步写入文件的辅助方法示例.

public async Task FileWriteAsync(string filePath, string messaage, bool append = true)
    {
        using (FileStream stream = new FileStream(filePath, append ? FileMode.Append : FileMode.Create, FileAccess.Write, FileShare.None, 4096, true))
        using (StreamWriter sw = new StreamWriter(stream))
        {
            await sw.WriteLineAsync(messaage);
        }
    }
Run Code Online (Sandbox Code Playgroud)


Ern*_*rno 5

异步写入文件不会解决此问题.您需要等待文件可用.