【问题标题】:How to refactor the async method to make it synchronous?如何重构异步方法以使其同步?
【发布时间】:2017-04-21 18:12:39
【问题描述】:

我需要同步运行以下异步代码:

using (var httpClient = new System.Net.Http.HttpClient())
      {
            var stream = GetStreamAsync(url);
            StreamReader reader = new StreamReader(url);
            jsonString = reader.ReadToEnd();
        }

完整代码如下:

protected override void OnCreate(Bundle savedInstanceState)
    {
        base.OnCreate(savedInstanceState);

        SetContentView(Resource.Layout.anim_layout);

        Animation myAnimation = AnimationUtils.LoadAnimation(this, Resource.Animation.MyAnimation);
        ImageView myImage = FindViewById<ImageView>(Resource.Id.imageView1);

        myImage.StartAnimation(myAnimation);

        FindViewById<Button>(Resource.Id.button1).Click+=delegate
        {
            StartActivity(new Intent(this, typeof(MainActivity)));
        };
    }

    public string dataByCity(string city)
    {
        var url = "http://api.openweathermap.org/data/2.5/weather?q=" + city + "&units=metric&APPID=" + AppID;

        //ТОРМОЗИТ ЗДЕСЬ / BRAKES HERE
        FetchAsync(url);
        return city;
    }

    public  double Data_down(double lat, double lon)
    {

        var url = String.Format(
          "http://api.openweathermap.org/data/2.5/weather?lat=" + lat + "&lon=" + lon + "&units=metric&APPID=" + AppID);

        //ТОРМОЗИТ ЗДЕСЬ / BRAKES HERE
        FetchAsync(url);

        return lat;
    }

    private void FetchAsync(string url)
    {
        string jsonString;

        using (var httpClient = new System.Net.Http.HttpClient())
        {
            var stream = GetStreamAsync(url);
            StreamReader reader = new StreamReader(url);
            jsonString = reader.ReadToEnd();
        }

        var json = jsonString;

        StartActivity(new Intent(this, typeof(MainActivity)));

        JsonValue firstitem = json;
        var mydata = JObject.Parse(json);

        cityTextGlobal = (mydata["name"]).ToString();

        string GovnoData = (mydata["main"]).ToString();

        //spliting string
        string[] values = GovnoData.Split(',');
        for (int i = 0; i < values.Length; i++)
        {
            values[i] = values[i].Trim();
            if (i == 0)
            {
                //tempGlobal = values[i];
                GovnoTemperature = values[i];
            }
        }
        tempGlobal = null;
        foreach (char c in GovnoTemperature)
        {
            if (c == '.')
            {
                break;
            }
            if (c == '-' || char.IsDigit(c) == true || c == '.')
            {
                tempGlobal += c.ToString();
            }
        }
        // startAct();

        //return jsonString;
    }

【问题讨论】:

标签: c# android xamarin


【解决方案1】:

将您的 FetchAsync 设为异步,然后您可以等待它。代码如下:

using (var httpClient = new HttpClient())
                {
                    var response = await httpClient.GetAsync(uri);
                    string tx = await response.Content.ReadAsStringAsync();                        
                }

【讨论】:

  • 我也看到了问题。你调用 StartActivity(new Intent(this, typeof(MainActivity)));在 FetchAsync 里面无条件地在函数中间。你预计会发生什么?
【解决方案2】:

首先,我想指出以下答案:How would I run an async Task<T> method synchronously?

由于不鼓励仅提供链接的答案,因此您可以尝试以下几点:

  • Task.RunSynchronously
  • Task.Wait - 这通常是 considered harmful/dangerous,因为将 Task.Wait 和 async/await 混合会导致死锁。
  • 只需在需要结果的地方使用“等待”即可。这并不是真正同步运行它(显然),但在大多数情况下是有效的。尝试运行异步的理由很少
  • 来自另一个答案:BlahAsync().GetAwaiter().GetResult()

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-02-24
    • 2013-05-14
    • 1970-01-01
    • 2015-03-29
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多