了解await& amp; async vs Task.Run

编程入门 行业动态 更新时间:2024-10-10 08:23:09
本文介绍了了解await& amp; async vs Task.Run的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧! 问题描述

大家好,

希望你一切都好。我试图了解在C#中使用await和async关键字的兴趣,但即使我发现了很多(可能更多)文章,我仍然无法理解什么是兴趣......我更熟悉任务创建和任务 continuation。

Hope you're all fine. I'm trying to understand interest of using await and async keywords in C#but even I found a lot (probably more) of articles, I'll still unable to understand what is the interest ... I'm morefamiliar with task creation and task continuation.

这是我创建的自定义类的示例。此类将以异步方式从数据库导入项目列表(例如,包含IP地址),并为每个项目启动新任务以测试ping的连接。序列每1分钟执行,并在需要时等待上一个序列完成。在下面的例子中,你能解释一下使用await& amp; async?

Here is an example of a custom class I created. This class will import a list of items (that contain IP address for example)from a database asynchronously and start a new task for each one to test connectivity from a ping. The sequence is executed every 1 minute and wait the previous sequence to be completed if needed.In the following example, can you explain me what would be the interest of using await & async ?

我不能把我的完整代码作为一个大项目的一部分,所以请随时告诉我你是否需要我做一些精确的事情。

I cannot put my full code as it's a part of a big project so feel free to tell me if you need me to precise a few things.

提前感谢您的帮助?

public class Monitor { public List<MyMonitoring> MonitoredItems { get; set; } public Task[] PingTasks { get; set; } public Dictionary<MyWatcher, bool?> Results { get; set; } public int SequenceID { get; set; } public IServer Server { get; set; } = new Server(); public System.Timers.Timer Timer { get; } = new System.Timers.Timer(60 * 1000 * 1); public BaseItem.Collection<MyWatcher> Watchers { get; set; } public Monitor() { Watchers = BaseItem.Collection<MyWatcher>.CreateAndFillAsync(UpdateMode.Never, false); // Load items from database asynchronously Watchers.TaskFill.ContinueWith(task => { Trace.TraceInformation("Loaded watchers list: {0} results", Watchers.Count); Results = Watchers.ToDictionary(w => w, w => (bool?)null); Timer.AutoReset = true; Timer.Elapsed += OnElapsed; Timer.Start(); PingTasks = GetNewSequence(); }); } public Task[] GetNewSequence() { var tasks = new List<Task>(); Trace.TraceInformation("Started new monitoring sequence (ID {0}) at {1}", ++SequenceID, DateTime.Now.ToShortDateString()); foreach (var w in Watchers) { var task = Task.Factory.StartNew(() => { var ping = new Ping(); var host = new IPAddress(w.IP).ToString(); var reply = ping.Send(host); Trace.TraceInformation("{0}: Ping to {1} = {2} (last reply = {3})", w.Name, host, reply.Status, w.LastReply); var connected = reply.Status == IPStatus.Success; if (!w.LastReply.HasValue || w.LastReply.HasValue && w.LastReply.Value != connected) { Trace.TraceInformation("{0}: Connectivity changed from {1} to {2}", w.Name, w.LastReply, connected); MyMonitoring.FromWatcher(w, connected).Write(); } w.LastReply = connected; Trace.TraceInformation("{0}: new state = {1}", w.Name, connected); }); } return tasks.ToArray(); } public void OnElapsed(object sender, System.Timers.ElapsedEventArgs e) { if (PingTasks != null) { Task.WaitAll(PingTasks); // Wait previous sequence to be terminated before starting a new one Trace.TraceInformation("Ended sequence monitoring (ID {0}) at {1})", SequenceID, DateTime.Now.ToShortDateString()); } PingTasks = GetNewSequence(); } }

推荐答案

你好NicolasC,

Hello NicolasC,

在我看来,await& async和Task.Run是一回事。前面的关键字(async,await)附带C#5.0,用于更方便地编写异步代码。我创建了一个简单的示例如下所示。

In my opinion, The await & async and Task.Run is the same thing. The former keywords(async,await) come with C# 5.0 and is designed for writing asynchronous code more conveniently. I created a simple exampleas below.

public class MyClass { public MyClass() { DisplayValue(); Console.WriteLine("MyClass() End."); } public Task<double> GetValueAsync(double num1, double num2) { return Task.Run(() => { for (int i = 0; i < 1000; i++) { num1 = num1 / num2; Thread.Sleep(1); } return num1; }); } public async void DisplayValue() { double result = await GetValueAsync(1234.5, 1.01); Console.WriteLine("Value is : " + result); } }

当你调用上面的代码时,结果将显示如下。

When you invoke the above code, the result will display as below.

MyClass()结束。 值是:0.0589002735288036

你会发现异步方法(DisplayValue) doesn' t阻止构造函数执行。在"DisplayValue"中方法,你会看到"等待"关键字,当主线程运行到那里时,它会立即返回。任务将被传递到另一个线程来执行。后续代码为"等待"在"DisplayValue"中方法将等待任务完成执行。它就像Task对象的continue方法一样。

You will find the asynchronous method (DisplayValue)doesn't block the constructor executing. In the "DisplayValue" method, you will see the "await" keyword, when main thread run to thereit will return immediately. The task will be delivered to another thread to execute. The behind code of "await" in "DisplayValue" method will wait the task finish executing. It just like the continue method of Task object.

实际上是"DisplayValue"。方法运行如下。

Actually the "DisplayValue" methodrun as below.

public void DisplayValue() { System.Runtime.CompilerServices.TaskAwaiter<double> awaiter = GetValueAsync(1234.5, 1.01).GetAwaiter(); awaiter.OnCompleted(() => { double result = awaiter.GetResult(); System.Diagnostics.Debug.WriteLine("Value is : " + result); }); }

因此,如果您将代码转换为使用 Async& Await,则代码应如下所示。

So if you convert your code to useAsync&Await, the code should be like as below.

public async void Monitor() { Watchers = await BaseItem.Collection<MyWatcher>.CreateAndFillAsync(UpdateMode.Never, false); // Load items from database asynchronously ... Trace.TraceInformation("Loaded watchers list: {0} results", Watchers.Count); Results = Watchers.ToDictionary(w => w, w => (bool?)null); Timer.AutoReset = true; Timer.Elapsed += OnElapsed; Timer.Start(); PingTasks = GetNewSequence(); ... }

有一个关于异步程序的官方文档,你可以参考它。

There is a official document about asynchronous program, you could take reference with it.

docs.microsoft/en-us/dotnet/csharp/async

祝你好运,

Neil Hu

更多推荐

了解await&amp; amp; async vs Task.Run

本文发布于:2023-11-03 23:43:11,感谢您对本站的认可!
本文链接:https://www.elefans.com/category/jswz/34/1556407.html
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。
本文标签:amp   await   async   Run   Task

发布评论

评论列表 (有 0 条评论)
草根站长

>www.elefans.com

编程频道|电子爱好者 - 技术资讯及电子产品介绍!