什么时候使用Task.Delay和Thread.Sleep有很好的规则?
一次又一次,我看到它说使用async- await不会创建任何额外的线程.这没有任何意义,因为计算机一次看起来只做一件事以上的唯一方法就是
因此,如果async- await这些都没有,那么它如何使应用程序响应?如果只有一个线程,则调用任何方法意味着在执行任何其他操作之前等待方法完成,并且该方法中的方法必须在继续之前等待结果,依此类推.
我最近正在阅读关于async/await的事情,我对以下事实感到困惑:我正在阅读的许多文章/帖子说明在使用异步等待时没有创建新线程(示例).
我创建了一个简单的控制台应用程序来测试它
class Program
{
static void Main(string[] args)
{
Console.WriteLine("Main: " + Thread.CurrentThread.ManagedThreadId);
MainAsync(args).Wait();
Console.WriteLine("Main End: " + Thread.CurrentThread.ManagedThreadId);
Console.ReadKey();
}
static async Task MainAsync(string[] args)
{
Console.WriteLine("Main Async: " + Thread.CurrentThread.ManagedThreadId);
await thisIsAsync();
}
private static async Task thisIsAsync()
{
Console.WriteLine("thisIsAsyncStart: " + Thread.CurrentThread.ManagedThreadId);
await Task.Delay(1);
Console.WriteLine("thisIsAsyncEnd: " + Thread.CurrentThread.ManagedThreadId);
}
}
Run Code Online (Sandbox Code Playgroud)
以下代码的输出是:
Main: 8
Main Async: 8
thisIsAsyncStart: 8
thisIsAsyncEnd: 9
Main End: 8
Run Code Online (Sandbox Code Playgroud)
我错过了这一点,或者这个AsyncEnd是否具有与其他操作不同的线程ID?
编辑:
我已根据下面的答案更新了代码await Task.Delay(1),但我仍然看到相同的结果.
引用下面的答案:
Rather, it enables the …Run Code Online (Sandbox Code Playgroud) 当我调用 foo() 时,该方法是否在单独的线程上运行?
public async Task<bool> foo(){
//Some code
}
Run Code Online (Sandbox Code Playgroud) 我有一个Web服务器,并有定期作业合并和发送记录(许多请求日志).
Task.Run(() =>
{
while (true)
{
try
{
MergeAndPutRecords();
}
catch (Exception ex)
{
Logger.Error(ex);
}
}
});
Run Code Online (Sandbox Code Playgroud)
在MergeAndPutRecords函数中,有代码合并记录和异步函数返回任务发送记录.(实际上它是亚马逊Kinesis Firehose的PutRecordBatchAsync.)
如果我在没有await关键字的情况下调用该函数会发生什么?函数是否在单独的线程上运行?这里说它不是.那么什么是返回任务手段?这里说async方法没有等待关键字的意思
- 在当前线程上启动异步方法.忽略所有结果(包括例外).
然后同时处理我的定期作业和PutRecordBatchAsync?我知道asynchronouse和concurrent是不同的.但是没有await关键字,它们在同一个线程中.首先执行哪一个?我很困惑......
会有大量记录需要合并并实时发送.所以我认为它必须同时执行..
我读过埃里克利珀的文章有关async,而约困惑的人曾与async关键字.他说 :
it(
async)表示"此方法包含涉及等待异步操作的控制流,因此将由编译器重写为连续传递样式,以确保异步操作可以在正确的位置恢复此方法." 异步方法的全部意义你尽可能地留在当前的线程上
我不明白这一点.如果我执行一个异步方法(Task)并且它运行,它肯定会在另一个线程上运行.
此外,如果我写的方法使用await,(IMHO)它释放正常的控制流,和代码重构 相似" ContinueWith"后,在另一个线程.
我用(控制台)测试了它:
/*1*/ public void StartChain()
/*2*/ {
/*3*/ var a = FuncA();
/*4*/ Console.WriteLine(a.Result);
/*5*/ }
/*6*/
/*7*/ public async Task < int > FuncA()
/*8*/ {
/*9*/ Console.WriteLine("A--" + Thread.CurrentThread.ManagedThreadId);
/*10*/ var t = await FuncB();
/*11*/ Console.WriteLine("B--" + Thread.CurrentThread.ManagedThreadId);
/*12*/ return t;
/*13*/ }
/*14*/
/*15*/ public async Task < int > …Run Code Online (Sandbox Code Playgroud) 我已经阅读了这个主题,该主题声称参考msdn并认为async/await不会创建新线程.请看下面的代码:
static class Program
{
static void Main(string[] args)
{
var task = SlowThreadAsync();
for(int i = 0; i < 5; i++)
{
Console.WriteLine(i * i);
}
Console.WriteLine("Slow thread result {0}", task.Result);
Console.WriteLine("Main finished on thread {0}", Thread.CurrentThread.ManagedThreadId);
Console.ReadKey();
}
static async Task<int> SlowThreadAsync()
{
Console.WriteLine("SlowThreadAsync started on thread {0}", Thread.CurrentThread.ManagedThreadId);
await Task.Delay(2000);
Console.WriteLine("SlowThreadAsync completed on thread {0}", Thread.CurrentThread.ManagedThreadId);
return 3443;
}
}
Run Code Online (Sandbox Code Playgroud)
由于这段代码我得到了不同的ThreadId.为什么同一个线程获得不同的ThreadId?
c# multithreading asynchronous task-parallel-library async-await
为什么await在C#方法中我们需要多个语句?
例如,这里有三个await语句:
using System;
using System.Threading.Tasks;
using Volo.Abp.Data;
using Volo.Abp.DependencyInjection;
using Volo.Abp.Domain.Repositories;
namespace Acme.BookStore
{
public class BookStoreDataSeederContributor
: IDataSeedContributor, ITransientDependency
{
private readonly IRepository<Book, Guid> _bookRepository;
public BookStoreDataSeederContributor(IRepository<Book, Guid> bookRepository)
{
_bookRepository = bookRepository;
}
public async Task SeedAsync(DataSeedContext context)
{
if (await _bookRepository.GetCountAsync() > 0)
{
return;
}
await _bookRepository.InsertAsync(
new Book
{
Name = "1984",
Type = BookType.Dystopia,
PublishDate = new DateTime(1949, 6, 8),
Price = 19.84f
}
);
await _bookRepository.InsertAsync( …Run Code Online (Sandbox Code Playgroud) 我对我在 .Net Core 库中看到的异常行为感到困惑。这个问题的目标是了解为什么它正在做我所看到的。
我认为当一个async方法被调用时,其中的代码会同步执行,直到遇到第一个 await。如果是这种情况,那么,如果在该“同步代码”期间抛出异常,为什么它不会传播到调用方法?(就像普通的同步方法一样。)
给定 .Net Core 控制台应用程序中的以下代码:
static void Main(string[] args)
{
Console.WriteLine("Hello World!");
try
{
NonAwaitedMethod();
}
catch (Exception e)
{
Console.WriteLine("Exception Caught");
}
Console.ReadKey();
}
public static async Task NonAwaitedMethod()
{
Task startupDone = new Task(() => { });
var runTask = DoStuff(() =>
{
startupDone.Start();
});
var didStartup = startupDone.Wait(1000);
if (!didStartup)
{
throw new ApplicationException("Fail One");
}
await runTask;
}
public static async Task DoStuff(Action …Run Code Online (Sandbox Code Playgroud) 我目前正在尝试用 Godot C# 制作一个基本的射手,对于枪的射速,我一直在尝试不同的延迟系统。尽管我试图使脚本通用,但节点计时器仍然有效,并且计时器调用似乎只调用父脚本中的函数。
\n我现在正在研究 C# 的 Task.Delay 方法,它似乎也可以工作,因为它是一个异步操作,它看起来不会受到帧速率的影响或减慢游戏速度。
\n我的问题是,在游戏应用程序中使用 Task.Delay 是否存在任何已知问题:比如它是否不可靠,或者如果调用该方法的实例过多,它会崩溃吗?
\n这是下面的代码,尽管我认为它\xe2\x80\x99s 并不重要:
\n private void shoot() {\n //if "canShoot" spawn bullet\n ShootCooledDown();\n}\n\nprivate async void ShootCooledDown() {\n TimeSpan span = TimeSpan.FromSeconds((double)(new decimal(shotDelay)));\n canShoot = false;\n await Task.Delay(span);\n canShoot = true;\n} \nRun Code Online (Sandbox Code Playgroud)\n c# ×9
async-await ×8
asynchronous ×4
.net ×1
.net-4.5 ×1
.net-core ×1
c#-5.0 ×1
exception ×1
godot ×1
task ×1