Zapis do pliku w metodzie asynchronicznej

Zapis do pliku w metodzie asynchronicznej
AZ
  • Rejestracja:około 3 lata
  • Ostatnio:10 miesięcy
  • Postów:15
0

Podpowiedzcie co trzeba zrobić, żeby zapisało i do pliku ten request:

Kopiuj
static void Main(string[] args)
{
 //To mi zapisuje
    File.AppendAllText(@"c:\TEMP\file.txt", "Rozpoczynam odczyt");
    Task.Run(new Action(GetEncoderCouter));
    
    
}

static HttpClient _client = new HttpClient();

static async void GetEncoderCouter()
{
    var result = await _client.GetAsync("http://10.0.3.225:8010/");
    string res = await result.Content.ReadAsStringAsync();
    if (result.IsSuccessStatusCode)
    {
        encoderClass enc = new encoderClass();
        enc = JsonConvert.DeserializeObject<encoderClass>(res);   
        //Tego nie zapisuje
        File.AppendAllText(@"c:\TEMP\file.txt", $"{DateTime.Now:f} {enc.counter}{Environment.NewLine}");            
    }
    
   
}

A może po prostu nie stosować metody asynchronicznej ?

Kopiuj

private static void Pobierz()
{
    try
    {
        HttpWebRequest request = (HttpWebRequest)WebRequest.Create("http://10.0.3.225:8010/");
        request.Method = "GET";
        HttpWebResponse webresponse;
        webresponse = (HttpWebResponse)request.GetResponse();

        Encoding encoding = System.Text.Encoding.GetEncoding(1250);
        StreamReader loResponseStream = new StreamReader(webresponse.GetResponseStream(), encoding);

        string Response = loResponseStream.ReadToEnd();

        loResponseStream.Close();
        webresponse.Close();

        encoderClass e = new encoderClass();
        e = JsonConvert.DeserializeObject<encoderClass>(Response);
        Console.WriteLine($"{DateTime.Now:yyyy-MM-dd HH-mm-ss}: {e.counter}{Environment.NewLine}");
        File.AppendAllText(@"c:\TEMP\file.txt", $"{DateTime.Now:yyyy-MM-dd HH-mm-ss}: {e.counter}{Environment.NewLine}");
    }
    catch (Exception ex)
    {

        Console.WriteLine(ex.Message);
        Console.ReadLine();
    }

}

AF
  • Rejestracja:prawie 18 lat
  • Ostatnio:około 2 miesiące
1

Task.Run(new Action(GetEncoderCouter));

Odpalasz zadanko, ale w ogóle na nie nie czekasz, brakuje Ci wszędzie awaitów.

AZ
  • Rejestracja:około 3 lata
  • Ostatnio:10 miesięcy
  • Postów:15
0

OK. Zrobiłam na dwa sposoby:

Działają obydwa, ale który jest lepszy? Dlaczego?

Kopiuj
class Program
{     
    static async Task Main(string[] args)
    {

        File.AppendAllText(@"c:\TEMP\file.txt", $"Rozpoczynam odczyt {Environment.NewLine}");
        await GetEncoderCouter();
        File.AppendAllText(@"c:\TEMP\file.txt", $"Koniec odczytu {Environment.NewLine}");
    }

    static HttpClient _client = new HttpClient();

    static async Task GetEncoderCouter()
    {
        var result = await _client.GetAsync("http://10.0.3.225:8010/");
        string res = await result.Content.ReadAsStringAsync();
        
        if (result.IsSuccessStatusCode)
        {
            encoderClass enc = new encoderClass();
            enc = JsonConvert.DeserializeObject<encoderClass>(res);
            File.AppendAllText(@"c:\TEMP\file.txt", $"{DateTime.Now:yyyy-MM-dd HH:mm:ss} {enc.counter}{Environment.NewLine}");
        } 
    }
         
}

Kopiuj
class Program
{
    static void Main(string[] args)
    {
        File.AppendAllText(@"c:\TEMP\file.txt", $"Rozpoczynam odczyt {Environment.NewLine}");
                    
        var res = Task<string>.Run(() => GetEncoderCouter());
        encoderClass enc = new encoderClass();
        enc = JsonConvert.DeserializeObject<encoderClass>(res.Result);

        File.AppendAllText(@"c:\TEMP\file.txt", $"{DateTime.Now:yyyy-MM-dd HH:mm:ss} {enc.counter}{Environment.NewLine}Koniec odczytu {Environment.NewLine}");
    }

    static async Task<string> GetEncoderCouter()
    {

        HttpClient _client = new HttpClient();
        var result = await _client.GetAsync("http://10.0.3.225:8010");
        string res = await result.Content.ReadAsStringAsync();
        return res;
    }
}

SO
  • Rejestracja:ponad 10 lat
  • Ostatnio:około rok
0

Pierwszy, bo tam masz prawdziwą asynhroniczność.

W drugim synchronicznie blokujesz stworzonego Taska (przez .Result) do momentu zakończenia operacji GetEncoderCounter.
Taski domyślnie uruchamiane są na wątkach z puli wątków (ThreadPool) i w drugim przypadku taki wątek zostanie zablokowany, a tych w domyślnych ustawieniach nie jest dużo i dodatkowe w miarę potrzeb tworzone są z opóźnieniem, więc przy większym ruchu (gdyby to było np. jakieś API) można doprowadzić do zagłodzenia puli wątków (o ile tak to się nazywa po polsku, chodzi mi o threadpool starvation).

Pomijam już fakt, że np. w apkach WinForms/WPF synchroniczne blokowanie na asynchronicznej operacji doprowadzi prawdopodobnie do deadlocka z uwagi na inny kontekst synchronizacji w tego typu aplikacjach (kontynuacje są schedulowane na wątku UI, a nie wątku z thread poola jak w przypadku apek konsolowych/ASP.NET Core).

AF
  • Rejestracja:prawie 18 lat
  • Ostatnio:około 2 miesiące
0
some_ONE napisał(a):

W drugim synchronicznie blokujesz stworzonego Taska (przez .Result) do momentu zakończenia operacji GetEncoderCounter.
Taski domyślnie uruchamiane są na wątkach z puli wątków (ThreadPool) i w drugim przypadku taki wątek zostanie zablokowany, a tych w domyślnych ustawieniach nie jest dużo i dodatkowe w miarę potrzeb tworzone są z opóźnieniem, więc przy większym ruchu (gdyby to było np. jakieś API) można doprowadzić do zagłodzenia puli wątków (o ile tak to się nazywa po polsku, chodzi mi o threadpool starvation).

Wszystko spoko, tylko asyncowy main jest cukrem składniowym na zaczekanie na taska. Twój opis jest mylący, jakby było po prostu GetEncoderCouter().Result, to nie byłoby różnicy w działaniu.

SO
W najprostszym przypadku tak, ale jak zechce odpalić ileś instancji tych swoich operacji i je zrównoleglić to już chyba będzie różnica. Cukier składniowy z async main zablokuje jeden wątek, a ona w pętli pozostałe. Przy await zamiast .Result według mnie zablokowany będzie tylko jeden wątek. Czy jednak źle myślę? ;)
AF

Zarejestruj się i dołącz do największej społeczności programistów w Polsce.

Otrzymaj wsparcie, dziel się wiedzą i rozwijaj swoje umiejętności z najlepszymi.