异步代码这么简单吗?

本文关键字:简单 代码 异步 | 更新日期: 2023-09-27 18:08:03

我正在开发一个c# Hue应用程序,我正在自己创建api调用以获得学习经验。由于Hue包含许多网络调用,所以我想为我创建的每个同步方法提供一个异步方法。我写了几行代码,对自己说"这不可能这么容易",所以现在我在这里,想问这是实现异步函数的好方法吗?此外,任何其他优化我的代码是赞赏的。

using System.IO;
using System.Net;
using System.Threading.Tasks;
using Newtonsoft.Json;
namespace SharpHue
{
    public class HueUtilities
    {
        const string DISCOVERY_URI = "http://www.meethue.com/api/nupnp";
        public struct DiscoveryElement
        {
            [JsonProperty("id")]
            public string ID;
            [JsonProperty("internalipaddress")]
            public string Address;
        }
        public static DiscoveryElement[] DiscoverBridges() 
        {
            string data = "[]";
            var request = WebRequest.CreateHttp(DISCOVERY_URI);
            try
            {
                var response = request.GetResponse();
                using (var streamReader = new StreamReader(response.GetResponseStream()))
                {
                    data = streamReader.ReadToEnd();
                    streamReader.Close();
                    response.Close();
                }
                return JsonConvert.DeserializeObject<DiscoveryElement[]>(data);
            }
            catch (Exception ex)
            {
                throw ex;
            }
        }
        public static async Task<DiscoveryElement[]> DiscoverBridgesAsync() 
        {
            return await Task.Run(() => DiscoverBridges());
        }
    }
}

异步代码这么简单吗?

差不多了。但是你应该避免Task。当有真正的异步替代方案时运行。在你的情况下,这意味着用HttpClient替换WebRequest类,并像这样调用你的代码:

public static async Task<DiscoveryElement[]> DiscoverBridgesAsync() 
{
    using (var client = new HttpClient())
    {
        var result = await client.GetAsync(DISCOVERY_URI);
        return await result.Content.ReadAsAsync<DiscoveryElement[]>();     
    }
}

可以看到,将同步调用包装为异步调用的方法不再使用。它现在是真正的async/await兼容。

警告可能有一些编译错误,但应该可以工作。

更多信息:http://www.asp.net/web-api/overview/advanced/calling-a-web-api-from-a-net-client

请读这个:http://www.ben-morris.com/why-you-shouldnt-create-asynchronous-wrappers-with-task-run/

没有async代码是众所周知的难以编写,这就是为什么他们添加了async关键字。问题往往是人们不理解async代码是什么,为什么要使用它。代码

var result = await Task.FromResult(0);

类似于

Task.FromResult(0).ContinueWith((task)=> 
            {
                var result = task.Result;
            });

如果代码不是异步的,使用async关键字不会使它如此。你的代码是异步的,因为什么任务。运行dose,而不是async关键字。像ReadStreamReadstreamAsync这样的东西实际上可能会做两种完全不同的事情,比如文件访问。的任务。Run在Asp之类的程序中就不一样了。Net和Wpf,因为asp没有UI线程。此外,任务与线程无关,它们可以在单个线程上运行,并且在某些情况下可以这样做。Akavache是如何在单线程上进行异步编程的一个很好的例子。如果你不知道在后台会做什么,你必须小心使用async。