Not
Bu sayfaya erişim yetkilendirme gerektiriyor. Oturum açmayı veya dizinleri değiştirmeyi deneyebilirsiniz.
Bu sayfaya erişim yetkilendirme gerektiriyor. Dizinleri değiştirmeyi deneyebilirsiniz.
Dosyalara erişmek için asenkron özelliği kullanarak, geri çağırmaları kullanmadan veya kodunuzu birden fazla yönteme veya lambda ifadesine bölmeden asenkron yöntemlere çağrı yapabilirsiniz. Zaman uyumlu kodu zaman uyumsuz yapmak için, zaman uyumlu bir yöntem yerine zaman uyumsuz bir yöntem çağırın ve koda birkaç anahtar sözcük ekleyin.
Şu nedenlerle dosya erişim çağrılarına asenkron eklemeyi düşünmeyi değerlendirin:
- Kullanıcı arabirimi iş parçacığı işlemi başlattığında başka işler gerçekleştirebildiğinden, senkron olmayan yapı kullanıcı arabirimi uygulamalarını daha duyarlı hale getirir. UI iş parçacığı uzun süren bir kodu yürütmesi gerektiğinde (örneğin, 50 milisaniyeden fazla), kullanıcı arabirimi G/Ç tamamlanana kadar donabilir ve UI iş parçacığı klavye ve fare girişlerini ve diğer olayları tekrar işlemeye başlayabilir.
- Zaman uyumsuzluğu, iş parçacığı gereksinimini azaltarak ASP.NET ve diğer sunucu tabanlı uygulamaların ölçeklenebilirliğini artırır. Uygulama yanıt başına ayrılmış bir iş parçacığı kullanıyorsa ve bin istek aynı anda işleniyorsa, bin iş parçacığı gerekir. Asenkron işlemler genellikle bekleme sırasında bir iş parçacığı kullanmayı gerektirmez. Mevcut G/Ç tamamlama iş parçacığını işin sonunda kısa bir süreliğine kullanırlar.
- Geçerli koşullarda dosya erişim işleminin gecikme süresi çok düşük olabilir, ancak gecikme süresi gelecekte büyük ölçüde artabilir. Örneğin, bir dosya dünyanın her yanındaki bir sunucuya taşınabilir.
- Asenkron özelliğini kullanmanın getirdiği ek yük küçüktür.
- Birden fazla zaman uyumsuz G/Ç işlemi, çağıran iş parçacığını engellemeden çalıştırılabilir.
Uygun sınıfları kullanma
Bu konudaki basit örnekler File.WriteAllTextAsync ve File.ReadAllTextAsync'i göstermektedir. Dosya G/Ç işlemleri üzerinde ayrıntılı denetim için, işletim sistemi düzeyinde eşzamanlı olmayan G/Ç'nin gerçekleşmesine olanak sağlayan bir seçeneğe sahip olan FileStream sınıfını kullanın. Bu seçeneği kullanarak, birçok durumda iş parçacığı havuzundaki bir iş parçacığını engellemekten kaçınabilirsiniz. Bu seçeneği etkinleştirmek için oluşturucu çağrısında useAsync=true veya options=FileOptions.Asynchronous bağımsız değişkenini belirtin.
Bu seçeneği, StreamReader ve StreamWriter dosya yolunu belirterek doğrudan açarsanız kullanamazsınız. Ancak, FileStream sınıfının açtığı bir Stream sağlarsanız bu seçeneği kullanabilirsiniz. Kullanıcı arabirimi iş parçacığı bekleme sırasında engellenmediğinden, bir iş parçacığı havuzu iş parçacığı engellenmiş olsa bile kullanıcı arabirimi uygulamalarında asenkron çağrılar daha hızlıdır.
Metin yazma
Aşağıdaki örneklerde dosyaya metin yazılır. Her bir await ifadesinde, metod hemen çıkış yapar. G/Ç dosyası tamamlandığında yöntemi await deyimini izleyen deyimde devam eder. "Asenkron değiştirici, await ifadesini kullanan yöntemlerin tanımında yer almaktadır."
Basit örnek
public async Task SimpleWriteAsync()
{
string filePath = "simple.txt";
string text = $"Hello World";
await File.WriteAllTextAsync(filePath, text);
}
Sonlu denetim örneği
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);
}
Özgün örnekte, aşağıdaki iki ifadenin birleşimi olan await sourceStream.WriteAsync(encodedText, 0, encodedText.Length); ifadesi vardır.
Task theTask = sourceStream.WriteAsync(encodedText, 0, encodedText.Length);
await theTask;
İlk ifade bir görev döndürür ve dosya işlemenin başlamasını sağlar. await ile ikinci ifade, yöntemin hemen çıkmasına ve farklı bir görevi döndürmesine neden olur. Dosya işleme işlemi daha sonra tamamlandığında yürütme, await öğesini izleyen deyimine döner.
Metni okuma
Aşağıdaki örneklerde bir dosyadan metin okunur.
Basit örnek
public async Task SimpleReadAsync()
{
string filePath = "simple.txt";
string text = await File.ReadAllTextAsync(filePath);
Console.WriteLine(text);
}
Sonlu denetim örneği
Metin arabelleğe alınır ve bu durumda bir StringBuilder içine yerleştirilir. Önceki örnekten farklı olarak, await'in değerlendirilmesi bir değer üretir.
ReadAsync yöntemi birTask<Int32> döndürür, bu nedenle await değerlendirmesi işlem tamamlandıktan sonra bir Int32 değer numRead üretir. Daha fazla bilgi için bkz. Zaman Uyumsuz Dönüş Türleri (C#).
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();
}
Birden çok eşzamansız G/Ç işlemi
Aşağıdaki örnekler birden çok zaman uyumsuz yazma işlemi başlatırlar. Çalışma zamanı bu işlemleri kuyruğa alır ve temel alınan uygulama platforma ve yapılandırmaya göre işletim sistemi (İS) asenkron G/Ç veya iş parçacığı havuzu iş parçacıklarını kullanabilir, bu nedenle gerçek eşzamanlılık işletim sistemine ve donanıma bağlıdır.
Basit örnek
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);
}
Sonlu denetim örneği
Her dosya için WriteAsync yöntemi, görev listesine eklenen bir görevi döndürür.
await Task.WhenAll(tasks); deyimi yöntemden çıkar ve tüm görevler için dosya işleme tamamlandığında yöntemde yeniden devam eder.
Örnek, görevler tamamlandıktan sonra bir FileStream bloktaki tüm finally örnekleri kapatır. Eğer her bir FileStream, bir using deyiminde oluşturulmuş olsaydı, FileStream, görev tamamlanmadan önce yok edilebilir.
Eşzamansız yaklaşım, G/Ç beklemedeyken çağıran iş parçacığının engellenmesini önler. Çoğu durumda aktarım hızı geliştirmeleri işletim sistemine, donanıma ve bazı platformlarda iş parçacığı havuzu sınırları ve zamanlama gibi .NET çalışma zamanı davranışına bağlıdır.
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();
}
}
}
WriteAsync ve ReadAsync yöntemlerini kullanırken, işlemi akışın ortasında iptal etmek için bir CancellationToken belirtebilirsiniz. Daha fazla bilgi için bkz. Yönetilen iş parçacıklarında iptal.