【问题标题】:Bing Maps REST Services Toolkit - Access Value Outside of Delegate必应地图 REST 服务工具包 - 访问代表之外的价值
【发布时间】:2019-04-04 18:01:31
【问题描述】:

此 Bing 地图 REST 服务工具包的示例代码使用委托来获取响应,然后从委托方法中输出消息。但是,它没有演示如何从调用 GetResponse 之外访问响应。我不知道如何从这个委托返回一个值。换句话说,假设我想在Console.ReadLine(); 行之前使用longitude 变量的值我如何在该范围内访问该变量?

    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    using System.Threading.Tasks;
    using BingMapsRESTToolkit;
    using System.Configuration;
    using System.Net;
    using System.Runtime.Serialization.Json;

    namespace RESTToolkitTestConsoleApp
    {

        class Program
        {

            static private string _ApiKey = System.Configuration.ConfigurationManager.AppSettings.Get("BingMapsKey");

            static void Main(string[] args)
            {
                string query = "1 Microsoft Way, Redmond, WA";

                Uri geocodeRequest = new Uri(string.Format("http://dev.virtualearth.net/REST/v1/Locations?q={0}&key={1}", query, _ApiKey));

                GetResponse(geocodeRequest, (x) =>
                {
                    Console.WriteLine(x.ResourceSets[0].Resources.Length + " result(s) found.");
                    decimal latitude = (decimal)((Location)x.ResourceSets[0].Resources[0]).Point.Coordinates[0];
                    decimal longitude = (decimal)((Location)x.ResourceSets[0].Resources[0]).Point.Coordinates[1];
                    Console.WriteLine("Latitude: " + latitude);
                    Console.WriteLine("Longitude: " + longitude);
                });
                Console.ReadLine();
            }

            private static void GetResponse(Uri uri, Action<Response> callback)
            {
                WebClient wc = new WebClient();
                wc.OpenReadCompleted += (o, a) =>
                {
                    if (callback != null)
                    {
                        // Requires a reference to System.Runtime.Serialization
                        DataContractJsonSerializer ser = new DataContractJsonSerializer(typeof(Response));
                        callback(ser.ReadObject(a.Result) as Response);
                    }
                };
                wc.OpenReadAsync(uri);
            }
        }
    }

【问题讨论】:

    标签: c# callback delegates bing-maps


    【解决方案1】:

    对于提供的示例AutoResetEvent class 可用于控制流程,特别是等待异步WebClient.OpenReadCompleted Event 完成如下:

    class Program
    {
        private static readonly string ApiKey = System.Configuration.ConfigurationManager.AppSettings.Get("BingMapsKey");
        private static readonly AutoResetEvent StopWaitHandle = new AutoResetEvent(false);
    
        public static void Main()
        {
            var query = "1 Microsoft Way, Redmond, WA";
            BingMapsRESTToolkit.Location result = null;
    
            Uri geocodeRequest = new Uri(string.Format("http://dev.virtualearth.net/REST/v1/Locations?q={0}&key={1}",
                query, ApiKey));
            GetResponse(geocodeRequest, (x) =>
            {
               if (response != null &&
                  response.ResourceSets != null &&
                  response.ResourceSets.Length > 0 &&
                  response.ResourceSets[0].Resources != null &&
                  response.ResourceSets[0].Resources.Length > 0)
               {
                   result = response.ResourceSets[0].Resources[0] as BingMapsRESTToolkit.Location;
                }
            });
            StopWaitHandle.WaitOne(); //wait for callback
            Console.WriteLine(result.Point); //<-access result 
            Console.ReadLine();
    
        }
    
        private static void GetResponse(Uri uri, Action<Response> callback)
        {
            var wc = new WebClient();
            wc.OpenReadCompleted += (o, a) =>
            {
                if (callback != null)
                {
                    DataContractJsonSerializer ser = new DataContractJsonSerializer(typeof(Response));
                    callback(ser.ReadObject(a.Result) as Response);
                }
                StopWaitHandle.Set(); //signal the wait handle
            };
            wc.OpenReadAsync(uri);
        }
    
    }
    

    选项 2

    或者切换到ServiceManager class,这样在通过asynchronous programming model 工作时更容易:

    public static void Main()
    {
        var task = ExecuteQuery("1 Microsoft Way, Redmond, WA");
        task.Wait();
        Console.WriteLine(task.Result);
        Console.ReadLine();
    }
    

    在哪里

    public static async Task<BingMapsRESTToolkit.Location> ExecuteQuery(string queryText)
    {
        //Create a request.
        var request = new GeocodeRequest()
            {
                Query = queryText,
                MaxResults = 1,
                BingMapsKey = ApiKey
        };
        //Process the request by using the ServiceManager.
        var response = await request.Execute();
        if (response != null &&
                response.ResourceSets != null &&
                response.ResourceSets.Length > 0 &&
                response.ResourceSets[0].Resources != null &&
                response.ResourceSets[0].Resources.Length > 0)
        {
             return response.ResourceSets[0].Resources[0] as BingMapsRESTToolkit.Location;
        }
        return null;
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2014-06-26
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-07-12
      • 2017-01-13
      相关资源
      最近更新 更多