Синхронизация C # с асинхронной функцией - PullRequest
0 голосов
/ 20 марта 2019

Как я могу изменить эту функцию на асинхронную с Framework 4.6.1?DGV имеет много данных и блокирует остальные процессы.

DGV обновляется каждые 30 секунд с таймером.

любое другое решение не блокирует следующий процесс, пока он не будет завершен?

У меня может быть что-то не так, я начинаю в мире программирования, и мне есть чему поучиться.

private void FillTimes()
        {
            var strResponse = CallJson($"RESTAPI URL");
            if (strResponse != null)
            {
                var jResult = JsonConvert.DeserializeObject<JsonResults>(strResponse);

                BindingSource bsResults = new BindingSource();
                bsResults.DataSource = jResult.Results;

                if (bsResults.DataSource != null)
                {
                    DgvOnline.DataSource = bsResults.DataSource;
                }
            }
        }

CallJson

 private string CallJson(string strURL)
            {
                RestTiming rJson = new RestTiming();
                rJson.endPoint = strURL;
                rJson.token = apiToken;

                string strResponse = string.Empty;

                strResponse = rJson.makeRequest();

                return strResponse;
            }

ResTiming

using System;
using System.IO;
using System.Net;
using System.Windows.Forms;

namespace Timing
{
    public enum httpVerb
    {
        GET,
        POST,
        PUT,
        DELETE

    }
    class RestTiming
    {
        public string endPoint { get; set; }
        public string token { get; set; }
        public httpVerb httpMethod { get; set; }
        public string userName { get; set; }
        public string userPassword { get; set; }
        public string postJSON { get; set; }

        public RestTiming()
        {
            endPoint = string.Empty;
            token = string.Empty;
        }

        public string makeRequest()
        {
            if (InternetAvailable())
            {
                string strResponseValue = string.Empty;

                HttpWebRequest request = (HttpWebRequest)WebRequest.Create(endPoint);

                request.Method = httpMethod.ToString();
                request.ContentType = "application/json";
                request.Accept = "application/json";
                request.Headers.Add("Authorization", token);
                request.UserAgent = @"Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/51.0.2704.106 Safari/537.36";

                if ((request.Method == "POST" || request.Method == "PUT") && postJSON != string.Empty)
                {
                    using (StreamWriter swJSONPayload = new StreamWriter(request.GetRequestStream()))
                    {
                        swJSONPayload.Write(postJSON);
                        swJSONPayload.Close();
                    }
                }

                HttpWebResponse response = null;

                try
                {
                    response = (HttpWebResponse)request.GetResponse();

                    // Process the response stream... (could be JSON, XML or HTML etc...)

                    using (Stream responseStream = response.GetResponseStream())
                    {
                        if (responseStream != null)
                        {
                            using (StreamReader reader = new StreamReader(responseStream))
                            {
                                strResponseValue = reader.ReadToEnd();
                            }// End of StreamReader
                        }
                    }// End of using ResponseStream

                }
                catch (WebException ex)
                {
                    if (ex.Status == WebExceptionStatus.ProtocolError && ex.Response != null)
                    {
                        var resp = (HttpWebResponse)ex.Response;
                        if (resp.StatusCode == HttpStatusCode.Unauthorized)
                        {
                            MessageBox.Show("Unauthorized", "Unauthorized", MessageBoxButtons.OK, MessageBoxIcon.Stop);
                            Environment.Exit(1);
                        }
                    }
                }

                return strResponseValue;
            }
            else
            {
                return null;
            }
        }

        private static Boolean InternetAvailable()
        {
            try
            {
                using (WebClient client = new WebClient())
                {
                    using (client.OpenRead("http://www.google.com/"))
                    {
                        return true;
                    }
                }
            }
            catch
            {
                return false;
            }
        }
    }
}

Спасибо

Ответы [ 3 ]

2 голосов
/ 20 марта 2019

Я не собираюсь взвешивать, должен ли ваш код быть асинхронным или нет.

Если вы хотите, чтобы синхронная работа выполнялась в фоновом потоке, вы можете выполнить ее с помощью Task.Run следующим образом:

private async Task FillTimes()
{
    return Task.Run(() => {
    {
        var strResponse = CallJson($"RESTAPI URL");
        if (strResponse != null)
        {
            var jResult = JsonConvert.DeserializeObject<JsonResults>(strResponse);

            BindingSource bsResults = new BindingSource();
            bsResults.DataSource = jResult.Results;

            if (bsResults.DataSource != null)
            {
                DgvOnline.DataSource = bsResults.DataSource;
            }
        }
    }
}
1 голос
/ 20 марта 2019

Обновлено

  class RestTiming
  {
    public string endPoint { get; set; }
    public string token { get; set; }
    public httpVerb httpMethod { get; set; }
    public string userName { get; set; }
    public string userPassword { get; set; }
    public string postJSON { get; set; }

    public RestTiming()
    {
        endPoint = string.Empty;
        token = string.Empty;
    }

    public async Task<string> makeRequest() //1. Changed to async and return type
    {
        if (InternetAvailable())
        {
            string strResponseValue = string.Empty;

            HttpWebRequest request = (HttpWebRequest)WebRequest.Create(endPoint);

            request.Method = httpMethod.ToString();
            request.ContentType = "application/json";
            request.Accept = "application/json";
            request.Headers.Add("Authorization", token);
            request.UserAgent = @"Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/51.0.2704.106 Safari/537.36";

            if ((request.Method == "POST" || request.Method == "PUT") && postJSON != string.Empty)
            {
                using (StreamWriter swJSONPayload = new StreamWriter(await request.GetRequestStreamAsync())) //2. changed to asynchronous call
                {
                    swJSONPayload.Write(postJSON);
                    swJSONPayload.Close();
                }
            }

            WebResponse response = null; //(a) updated

            try
            {
                response =await request.GetResponseAsync(); 

                // Process the response stream... (could be JSON, XML or HTML etc...)

                using (Stream responseStream =response.GetResponseStream()) //(b) updated
                {
                    if (responseStream != null)
                    {
                        using (StreamReader reader = new StreamReader(responseStream))
                        {
                            strResponseValue = await reader.ReadToEndAsync(); // (c) updated
                        }// End of StreamReader
                    }
                }// End of using ResponseStream

            }
            catch (WebException ex)
            {
                if (ex.Status == WebExceptionStatus.ProtocolError && ex.Response != null)
                {
                    var resp = (HttpWebResponse)ex.Response;
                    if (resp.StatusCode == HttpStatusCode.Unauthorized)
                    {
                        MessageBox.Show("Unauthorized", "Unauthorized", MessageBoxButtons.OK, MessageBoxIcon.Stop);
                        Environment.Exit(1);
                    }
                }
            }

            return strResponseValue;
        }
        else
        {
            return null;
        }
    }

    private static Boolean InternetAvailable()
    {
        try
        {
            using (WebClient client = new WebClient())
            {
                using (client.OpenRead("http://www.google.com/"))
                {
                    return true;
                }
            }
        }

Изменения во втором методе

private async Task<string> CallJson(string strURL) //1. Changed to async and return type
        {
            RestTiming rJson = new RestTiming();
            rJson.endPoint = strURL;
            rJson.token = apiToken;

            string strResponse = string.Empty;

            strResponse =await rJson.makeRequest(); //2. made asynchronous 

            return strResponse;
        }

Изменение в первом методе

    private async Task FillTimes() // 1. Make async and change return type
    {
        var strResponse =await CallJson($"RESTAPI URL"); // 2. add await to make asynchronous
        ...
    }

Пожалуйста, дайте мне знать, если это поможет. Кроме того, проверьте эту ссылку ( Получение ответа асинхронного запроса HttpWebRequest )

1 голос
/ 20 марта 2019

Обновление

Если CallJson является IO Bound , то вы можете сделать это async, также вы добавите суффикс Async кимя метода должно быть согласованным.Ваш полученный метод будет выглядеть следующим образом.

private async Task FillTimes()
{
   var strResponse = await CallJsonAsync($"RESTAPI URL");
   if (strResponse != null)
   {
      var jResult = JsonConvert.DeserializeObject<JsonResults>(strResponse);

      BindingSource bsResults = new BindingSource();
      bsResults.DataSource = jResult.Results;

      if (bsResults.DataSource != null)
      {
         DgvOnline.DataSource = bsResults.DataSource;
      }
   }
}

А ваш async метод будет выглядеть следующим образом

private async Task<responseType> CallJsonAsync(<something>)
{
    ... 

    await SomethingAsync(...);

    ...

    return something;
}

Оригинал

Как я могу изменить эту функцию на асинхронную с помощью Framework 4.6.1

Нет очевидной IO Bound работы и нет метода, который поддается asyncпозвонить (что я вижу).

Итак, чтобы ответить на вопрос: « Как я могу изменить эту функцию на async? », ответ вам не следует, пусть она будет синхронной.

Если это не обновляет UI , вы можете вызвать этот метод из Task и await, которые

...