c# - Gitlab Api - problem ze wynikiem z metody asynchronicznej

c# - Gitlab Api - problem ze wynikiem z metody asynchronicznej
aksimoN
  • Rejestracja:prawie 7 lat
  • Ostatnio:11 miesięcy
  • Postów:88
0

Napisałem metodę która ma zwracać id projektu z gitlab api przyjmując na wejściu nazwę projektu :

Kopiuj
static async Task<int> find_id(string repository, string AppName)
 {            
                using (var httpClient = new HttpClient()) // GET AppID

                {
                    string issue_path = which_repo(repository)[0]+ "search?scope=projects&search="+AppName;
                    using (var request = new HttpRequestMessage(new HttpMethod("GET"), issue_path))
                    {       
                            request.Headers.TryAddWithoutValidation("PRIVATE-TOKEN", which_repo(repository)[1]);
                            var response = await httpClient.SendAsync(request);
                            var content = await response.Content.ReadAsStringAsync();
                            List<Project> projects = new List<Project>();
                            projects = JsonConvert.DeserializeObject<List<Project>>(content);
                            Project result = projects.FirstOrDefault(item => item.@namespace.full_path != "archiwum" );
                            Console.WriteLine("PROJECT: " + result.name_with_namespace + " ID: "+result.id);
                            return result.id;
                    }
             
             }  
}          

Mam tylko problem ponieważ gdy wywołuję

Kopiuj
Task<int> id =  find_id("repo", appName);
Console.WriteLine(id);

Najpierw otrzymuję

Kopiuj
System.Threading.Tasks.Task`1[System.Int32]

a potem odpowiedni wynik wykonania linii

Kopiuj
Console.WriteLine("PROJECT: " + result.name_with_namespace + " ID: "+result.id); 

Wiem że ma to związek z tym że to metoda async ale nadal nie czuje tego do końca i dlatego pytam tutaj.

edytowany 2x, ostatnio: aksimoN
AdamWox
Po co ci ten pierwszy HttpClient skoro go nigdzie nie używasz?
aksimoN
Za dużo przekopiowałem z poprzedniego kodu który w tym próbuję bardziej rozpisać na metody, już poprawione
AdamWox
  • Rejestracja:ponad 7 lat
  • Ostatnio:około 4 godziny
  • Lokalizacja:Jastrzębie-Zdrój
  • Postów:2161
1

Zrób

Kopiuj
int id =  await findId("repo", appName);

Lub

Kopiuj
int id =  findId("repo", appName).Result;
edytowany 1x, ostatnio: AdamWox
aksimoN
Zadziałało to drugie, to ten tak zwany unwrap?
SA
Nie po to metody są async, żeby je blokować z .Result.
AdamWox
To mu to wytłumacz 😜
aksimoN
Chętnie się dowiem, może w ogóle nie powinienem tej metody pisać jako async?
SA
  • Rejestracja:ponad 12 lat
  • Ostatnio:około 20 godzin
  • Postów:1435
0
Kopiuj
using (var httpClient = new HttpClient())

Przy okazji nie twórz za każdym razem nowego klienta, wystarczy Ci jeden jako w static albo wstrzykuj go przez DI.

Edit:
Milej by się patrzyło gdybyś respektował przyjęte standardy nazewnictwa, bo nie wiem czy wcześniej pisałeś w Javie (camel case) czy w jakimiś Ruby/Pythonie (snake case).

edytowany 1x, ostatnio: Saalin
SO
Przy okazji nie twórz za każdym razem nowego klienta, wystarczy Ci jeden jako w static albo wstrzykuj go przez DI. Najlepiej to użyć HttpClientFactory. Z singletonem czy statycznym klientem też występują specyficzne problemy - np. nie potrafi odświeżyć sobie DNSów.
aksimoN
Chyba nie jestem tak biegły żeby to ogarnąć: "wystarczy Ci jeden jako w static albo wstrzykuj go przez DI." - możesz troszeczkę szerzej?
SA
@aksimoN: tworzenie HttpClient z usign to antipattern, za dokumentacją Instantiating an HttpClient class for every request will exhaust the number of sockets available under heavy loads https://docs.microsoft.com/en-us/dotnet/api/system.net.http.httpclient?view=net-5.0 Rozwiązanie to jedna instancja HttpClienta lub factory proponowane przez @some_ONE
aksimoN
  • Rejestracja:prawie 7 lat
  • Ostatnio:11 miesięcy
  • Postów:88
0

@Saalin: Mam nadzieję że o to chodziło?

Kopiuj
static readonly HttpClient client = new HttpClient();
static async Task<int> find_id(string repository, string AppName)
        {          
                                 
                    string issue_path = which_repo(repository)[0]+ "search?scope=projects&search="+AppName;
                    using (var request = new HttpRequestMessage(new HttpMethod("GET"), issue_path))
                    {       
                            request.Headers.TryAddWithoutValidation("PRIVATE-TOKEN", which_repo(repository)[1]);
                            var response = await client.SendAsync(request);
                            var content = await response.Content.ReadAsStringAsync();
                            List<Project> projects = new List<Project>();
                            projects = JsonConvert.DeserializeObject<List<Project>>(content);
                            Project result = projects.FirstOrDefault(item => item.@namespace.full_path != "archiwum" );                            
                            return result.id;
                    }

                
                       
        }
edytowany 1x, ostatnio: aksimoN

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.