C# 异步写入文件
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/11774827/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Writing to a file asynchronously
提问by CPK_2011
Is there any way to write an asynchronous function that writes to data to a file repeatedly.
有什么方法可以编写一个异步函数,重复地将数据写入文件。
I am getting the following error when I write asynchronous function
编写异步函数时出现以下错误
The process cannot access the file 'c:\Temp\Data.txt' because it is being used by another process
该进程无法访问文件“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();
}
}
采纳答案by curiousBoy
Well I had the same problem. And solved it now. It is kind of late suggestion but may be help for others.
好吧,我遇到了同样的问题。现在解决了。这是一种迟到的建议,但可能对其他人有所帮助。
Include the following using statements in the console examples below.
在下面的控制台示例中包含以下 using 语句。
using System;
using System.Collections.Generic;
using System.IO;
using System.Text;
using System.Threading.Tasks;
Use of the FileStream Class
The examples below use the FileStream class, which has an option that causes asynchronous I/O to occur at the operating system level. In many cases, this will avoid blocking a ThreadPool thread. To enable this option, you must specify the useAsync=true or options=FileOptions.Asynchronous argument in the constructor call.
下面的示例使用 FileStream 类,该类具有导致在操作系统级别发生异步 I/O 的选项。在许多情况下,这将避免阻塞 ThreadPool 线程。要启用此选项,您必须在构造函数调用中指定 useAsync=true 或 options=FileOptions.Asynchronous 参数。
StreamReader and StreamWriter do not have this option if you open them directly by specifying a file path. StreamReader/Writer do have this option if you provide them a Stream that was opened by the FileStream class. Note that asynchrony provides a responsiveness advantage in UI apps even if a thread pool thread is blocked, since the UI thread is not blocked during the wait.
StreamReader 和 StreamWriter 如果通过指定文件路径直接打开它们,则没有此选项。如果您向它们提供由 FileStream 类打开的 Stream,则 StreamReader/Writer 确实具有此选项。请注意,即使线程池线程被阻塞,异步也会在 UI 应用程序中提供响应优势,因为 UI 线程在等待期间不会被阻塞。
Writing Text
书写文字
The following example writes text to a file. At each await statement, the method immediately exits. When the file I/O is complete, the method resumes at the statement following the await statement. Note that the async modifier is in the definition of methods that use the await statement.
以下示例将文本写入文件。在每个 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);
};
}
Reading Text
阅读文本
The following example reads text from a file. The text is buffered and, in this case, placed into a StringBuilder. Unlike in the previous example, the evaluation of the await produces a value. The ReadAsync method returns a Task, so the evaluation of the await produces an Int32 value (numRead) that is returned after the operation completes..
以下示例从文件中读取文本。文本被缓冲,在这种情况下,被放入一个 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();
}
}
You can take a look original source from Using Async for File Access
您可以从Using Async for File Access 中查看原始来源
Hope that helps...
希望有帮助...
回答by Erno
Writing asynchronously to the file will not solve this issue. You'll need to wait for the file to be available.
异步写入文件不会解决这个问题。您需要等待文件可用。
回答by Pharap
Ultimately it depends why you're trying to do it.
最终,这取决于您为什么要尝试这样做。
If you aren't going to be writing too much data to the file, you can constantly open and close it.
如果您不打算向文件写入太多数据,则可以不断地打开和关闭它。
Alternatively, if you know when you want the file open and when you want it closed, you can open it when it's needed, then keep it open for writing until the point you know it's no longer needed.
或者,如果您知道文件何时打开和何时关闭,您可以在需要时打开它,然后保持打开状态以进行写入,直到您知道不再需要它为止。
回答by SteveD
Example of a helper method to handle async writing to a file.
处理异步写入文件的辅助方法示例。
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);
}
}

