简体   繁体   中英

How to refactor the async method to make it synchronous?

I need to run the following async code synchronously:

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

The full code looks:

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;
    }

First, I would like to point out the following answer: How would I run an async Task<T> method synchronously?

Since link-only answers are discouraged, here are a few things mentioned there that you could try:

  • Task.RunSynchronously
  • Task.Wait - this is often considered harmful/dangerous because mixing Task.Wait and async/await can result in deadlocks.
  • Just use "await" where you need the result. This isn't really running it synchronously (obviously) but in most cases that works. There are rarely good reasons to try to run an asynchronous
  • From the other answer: BlahAsync().GetAwaiter().GetResult()

Make your FetchAsync to be async then you can await on it. The code as below:

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

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM