我有以下代码,
private void button1_Click(object sender, RoutedEventArgs e)
{
button1.IsEnabled = false;
var s = File.ReadAllLines("Words.txt").ToList(); // my WPF app hangs here
// do something with s
button1.IsEnabled = true;
}
Run Code Online (Sandbox Code Playgroud)
Words.txt有很多单词,我读入s变量,我试图利用C#5中的async和await关键字,Async CTP Library所以WPF应用程序不会挂起.到目前为止,我有以下代码,
private async void button1_Click(object sender, RoutedEventArgs e)
{
button1.IsEnabled = false;
Task<string[]> ws = Task.Factory.FromAsync<string[]>(
// What do i have here? there are so many overloads
); // is this the right way to do?
var s = await File.ReadAllLines("Words.txt").ToList(); …Run Code Online (Sandbox Code Playgroud) 我在网上搜索过,看过很多关于task.run和等待异步的问题,但是有一个特定的使用场景,我并不是真的了解它的区别.我相信情景非常简单.
await Task.Run(() => LongProcess());
Run Code Online (Sandbox Code Playgroud)
VS
await LongProcess());
Run Code Online (Sandbox Code Playgroud)
其中LongProcess是一个异步方法,其中包含一些异步调用,例如调用db并等待ExecuteReaderAsync().
题:
这种情况下两者之间有什么区别吗?感谢任何帮助或意见,谢谢!
为什么下面的代码导致:
public static class Program
{
public static void Main(params string[] args)
{
var sourceFileName = @"C:\Users\ehoua\Desktop\Stuff\800MFile.exe";
var destinationFileName = sourceFileName + ".bak";
FileCopyAsync(sourceFileName, destinationFileName);
// The line below is actually faster and a lot less CPU-consuming
// File.Copy(sourceFileName, destinationFileName, true);
Console.ReadKey();
}
public static async void FileCopyAsync(string sourceFileName, string destinationFileName, int bufferSize = 0x1000, CancellationToken cancellationToken = default(CancellationToken))
{
using (var sourceFile = File.OpenRead(sourceFileName))
{
using (var destinationFile = File.OpenWrite(destinationFileName))
{
Console.WriteLine($"Copying {sourceFileName} to {destinationFileName}...");
await sourceFile.CopyToAsync(destinationFile, bufferSize, cancellationToken); …Run Code Online (Sandbox Code Playgroud) 我在测试 C# 8.0 功能时遇到了 IAsyncEnumerable。我从 Anthony Chu ( https://anthonychu.ca/post/async-streams-dotnet-core-3-iasyncenumerable/ ) 中找到了非凡的例子。它是异步流和替代Task<IEnumerable<T>>
// Data Access Layer.
public async IAsyncEnumerable<Product> GetAllProducts()
{
Container container = cosmosClient.GetContainer(DatabaseId, ContainerId);
var iterator = container.GetItemQueryIterator<Product>("SELECT * FROM c");
while (iterator.HasMoreResults)
{
foreach (var product in await iterator.ReadNextAsync())
{
yield return product;
}
}
}
// Usage
await foreach (var product in productsRepository.GetAllProducts())
{
Console.WriteLine(product);
}
Run Code Online (Sandbox Code Playgroud)
我想知道这是否可以应用于读取文本文件,例如下面逐行读取文件的用法。
foreach (var line in File.ReadLines("Filename"))
{
// ...process line.
}
Run Code Online (Sandbox Code Playgroud)
我真的很想知道如何将 async withIAsyncEnumerable<string>()应用于上述 foreach 循环,以便在阅读时进行流式传输。
如何实现迭代器以便我可以使用 yield …
我正在尝试异步读取文件。我想知道这是否是这样做的正确方法。以下是我迄今为止尝试过的。这样对吗?
static void Main(string[] args)
{
Task<string> readFileTask = Task.Run(() => ReadFile(@"C:\Users\User\Desktop\Test.txt"));
readFileTask.Wait();
string astr = readFileTask.Result;
Console.WriteLine(astr);
}
static private async Task<string> ReadFile(string filePath)
{
string text = File.ReadAllText(filePath);
return text;
}
Run Code Online (Sandbox Code Playgroud)
谢谢。
C# 中的许多内置 IO 函数都是非阻塞的,也就是说,它们在等待操作完成时不会保留线程。
例如System.IO.File.ReadAllLinesAsync返回 aTask<string[]>是非阻塞的。
它不只是暂停正在使用的线程,实际上还释放了该线程,以便其他进程可以使用它。
我认为这是通过调用操作系统来实现的,操作系统在检索文件时回调程序,而程序不必浪费线程等待它。
是否可以自己创建一个非阻塞异步任务?
显然,做类似的事情Thread.sleep()不会像那样释放当前线程System.IO.File.ReadAllLinesAsync。
我意识到休眠线程不会占用 CPU 资源,但它仍然占用一个线程,这在处理大量请求的 Web 服务器中可能会出现问题。
我不是在谈论一般如何生成任务。我正在谈论用于处理文件/网络调用的内置 C# 函数如何在等待时释放线程。
我需要从网络连接存储平台读取大文件(50-500 GB)的不同部分,并对其进行一些处理,并且我需要非常快速地完成此操作。
我正在使用 .net5、golang 和 c++ 编写应用程序,并发布适用于所有平台(Windows、Linux、MacOS)的代码
当我为 Linux 和 MacOS 发布下面的并行代码时,它工作得很好,并且与单线程方法相比,我获得了并行读取的好处(例如 4x-32x 取决于 CPU 核心的数量)。
然而,使用相同的硬件配置和相同的代码,与单线程方法相比,我在使用并行方法的 Windows 机器上没有得到任何性能影响。
另一个意想不到的行为是,当我在 Linux 平台上使用 GOLANG 编写相同的逻辑时,不同的发行版显示不同的行为。例如,只有当存储设备使用 NFS 协议挂载时,我的代码才能在 ubuntu 上进行并行读取。然而,在 CentOS 中,它可以通过两种配置(NFS 和块存储)进行并行读取。
所以我很困惑。
另外,您还可以在下面找到我为此场景准备的基准测试工具。
我知道这个问题是一个非常小众的问题,只对使用网络存储设备的人感兴趣,但如果某些操作系统或存储或软件人员可以对此发表评论,我会尝试我的更改。谢谢大家。
C# 中的单线程方法
//Store max of each section
int[] maxBuffer = new int[numberOfSections];
using (FileStream streamSource = new FileStream(filePath, FileMode.Open, FileAccess.Read, FileShare.Read, 4096, FileOptions.Asynchronous))
{
for (int index = 0; index < numberOfSections; index++) …Run Code Online (Sandbox Code Playgroud) 当我需要一些并行处理时,通常会这样:
static void Main(string[] args)
{
var tasks = new List<Task>();
var toProcess = new List<string>{"dog", "cat", "whale", "etc"};
toProcess.ForEach(s => tasks.Add(CanRunAsync(s)));
Task.WaitAll(tasks.ToArray());
}
private static async Task CanRunAsync(string item)
{
// simulate some work
await Task.Delay(10000);
}
Run Code Online (Sandbox Code Playgroud)
在某些情况下,我无法并行处理这些项目,而不得不使用Task.Run它来强制它在不同的线程上运行。
我想念什么?
在使用asyncand时await,有时我会遇到一个让我讨厌使用它的地方,因为我觉得它毫无意义。我还没有成功证明情况也是如此(而且,诚然,保留它不会损害性能)。我如何在以下示例中验证(或拒绝)我的主张。
bool empty = await Context.Stuff.AnyAsync();
if(empty)
throw new Exception();
Run Code Online (Sandbox Code Playgroud)
我的主张是 - 由于我们立即使用检查结果来验证是否应该离开该方法,因此该调用需要同步启动。因此,我相信以下内容没有更差的表现。
bool empty = Context.Stuff.Any();
if(empty)
throw new Exception();
Run Code Online (Sandbox Code Playgroud)
我如何验证我的主张(除了经验之外)?
如果我有这个
static void Main(string[] args)
{
var tasks = new List<Task>();
for (int i = 0; i < 10; i++)
{
tasks.Add(AsyncWithBlockingIO(i));
}
Task.WaitAll(tasks.ToArray());
}
private static async Task AsyncWithBlockingIO(int fileNum)
{
var result = await File.ReadAllTextAsync($"File{fileNum}").ConfigureAwait(false);
//will the below run concurrently on multiple threads?
CpuNoIOWork(result);
}
Run Code Online (Sandbox Code Playgroud)
将CpuNoIOWork()同时运行多个线程(使用线程池)作为IO调用完成还是会只使用1个线程在同一时间?
似乎在 Blazor 服务器应用程序中,我们鼓励尽可能使用异步,我通常理解原因。也就是说 - 请有人好心地解释一下使用异步函数时的一般期望并为我填写一些缺失的知识 - 我对所有的信息感到困惑,需要一些针对我正在做的事情的具体信息,以帮助我理解。
我试图尽可能坚持使用异步,并且在大多数情况下这样做相当容易,但是在调用某些函数时,使它们异步似乎有点矫枉过正(或者是吗?)。在下面的示例中 - 从异步函数内调用非异步“ValidateEvent”函数。
所以我的问题是......我应该:
a)从异步函数中正常调用它(这似乎违背了异步的要点),例如:“varvalidationResult = ValidateEvent(objDto);”?
b)使用 Task.Run 调用它,例如:“await Task.Run(() =>ValidateEvent(objDto));”?
c)将这个简单的 IF/ELSE 方法转换为异步函数?
预先感谢您的任何帮助/建议。
//example async function, that itself calls the other non-async function.
public async Task<Response> AddAsync(ObjDto objDto)
{
// a) Call it normally?
var validationResult = ValidateEvent(objDto);
// b) Calling it using Task.Run?
var validationResult = await Task.Run(() =>ValidateEvent(objDto));
//Do stuff asynchronously here
...
await _db.AddAsync(objDto);
await _db.SaveChangesAsync();
...
}
Run Code Online (Sandbox Code Playgroud)
验证函数:
c) 我真的应该将其转换为异步吗,因为它只是一系列“IF 和 ELSE”(异步转换见下文)
//Non-Async …Run Code Online (Sandbox Code Playgroud) c# ×11
async-await ×7
asynchronous ×6
.net ×4
.net-6.0 ×1
c#-5.0 ×1
c#-8.0 ×1
console ×1
file-copying ×1
go ×1
io ×1
nfs ×1
storage ×1
task ×1