버튼 클릭 시 비동기 메서드 호출
Windows Phone 8.1 프로젝트를 만들고 실행하려고 합니다.async방법GetResponse<T>(string url)버튼을 클릭하고 메서드가 완료되기를 기다리지만 메서드가 완료되지 않습니다.내 코드는 다음과 같습니다.
private void Button_Click(object sender, RoutedEventArgs
{
Task<List<MyObject>> task = GetResponse<MyObject>("my url");
task.Wait();
var items = task.Result; //break point here
}
public static async Task<List<T>> GetResponse<T>(string url)
{
List<T> items = null;
HttpWebRequest request = (HttpWebRequest)HttpWebRequest.Create(url);
var response = (HttpWebResponse)await Task.Factory.FromAsync<WebResponse>(request.BeginGetResponse, request.EndGetResponse, null);
try
{
Stream stream = response.GetResponseStream();
StreamReader strReader = new StreamReader(stream);
string text = strReader.ReadToEnd();
items = JsonConvert.DeserializeObject<List<T>>(text);
}
catch (WebException)
{
throw;
}
return items;
}
그것은 계속될 것입니다.task.Wait().
버튼 클릭 방법을 다음으로 변경했습니다.async및 사용된await이전에async방법과 나는 결과를 얻습니다(await GetResponse<string>("url"). 무엇이 문제입니까?Task<List<string>> task = GetResponse<string>("url")내가 뭘 잘못하고 있는 거지?
도와주셔서 감사합니다!
당신은 전형적인 교착 상태의 희생자입니다. task.Wait()또는task.Result교착 상태를 유발하는 UI 스레드의 차단 호출입니다.
UI 스레드를 차단하지 마십시오.절대 하지 마세요.그저.await그것.
private async void Button_Click(object sender, RoutedEventArgs
{
var task = GetResponseAsync<MyObject>("my url");
var items = await task;
}
그나저나, 당신은 왜 그것을 잡습니까?WebException그리고 그것을 다시 버리는 것?그냥 잡지 않는 게 좋을 것 같아요.둘 다 똑같아요.
또한 저는 당신이 비동기 코드와 동기 코드를 혼합하는 것을 볼 수 있습니다.GetResponse방법. StreamReader.ReadToEnd차단 통화입니다. 사용해야 합니다.StreamReader.ReadToEndAsync.
또한 "Async" 접미사를 Jon의 말처럼 TAP("Task based Asynchronous Pattern") 규약을 따르도록 작업을 반환하거나 비동기식을 반환하는 메서드에 사용합니다.
위의 우려 사항을 모두 해결한 경우 다음과 같은 방법을 사용해야 합니다.
public static async Task<List<T>> GetResponseAsync<T>(string url)
{
HttpWebRequest request = (HttpWebRequest)HttpWebRequest.Create(url);
var response = (HttpWebResponse)await Task.Factory.FromAsync<WebResponse>(request.BeginGetResponse, request.EndGetResponse, null);
Stream stream = response.GetResponseStream();
StreamReader strReader = new StreamReader(stream);
string text = await strReader.ReadToEndAsync();
return JsonConvert.DeserializeObject<List<T>>(text);
}
이것이 당신을 죽이는 것입니다.
task.Wait();
작업이 완료될 때까지 UI 스레드를 차단합니다. 그러나 작업은 "일시 중지"된 후 UI 스레드로 돌아가 비동기 결과를 기다리는 비동기 메서드입니다.UI 스레드를 차단하고 있기 때문에 그럴 수 없습니다.
코드에는 UI 스레드에 있어야 할 것처럼 보이는 것이 없습니다. 하지만 실제로 UI 스레드에 있어야 한다고 가정하면 다음을 사용해야 합니다.
private async void Button_Click(object sender, RoutedEventArgs
{
Task<List<MyObject>> task = GetResponse<MyObject>("my url");
var items = await task;
// Presumably use items here
}
아니면 그냥:
private async void Button_Click(object sender, RoutedEventArgs
{
var items = await GetResponse<MyObject>("my url");
// Presumably use items here
}
이제 작업이 완료될 때까지 차단하는 대신,Button_Click메서드는 작업이 완료되면 계속 실행을 예약한 후 반환됩니다.(기본적으로 비동기/대기 방식입니다.)
이름도 변경할 수 있습니다.GetResponse로.GetResponseAsync알기 쉽게
@Chris Walsh: 작업을 사용하는 경우.()를 실행하고 해당 함수 안에서 비동기 작업을 호출하면 작업이 새 UI 스레드에서 실행되어 UI가 차단되지 않습니다.
아래 코드를 사용
Task.WaitAll(Task.Run(async () => await GetResponse<MyObject>("my url")));
언급URL : https://stackoverflow.com/questions/28601678/calling-async-method-on-button-click
'programing' 카테고리의 다른 글
| 현재 사용 중인 대화형 셸을 확인하는 방법(명령줄) (0) | 2023.05.29 |
|---|---|
| iOS 10에서 Xcode 7 사용 (0) | 2023.05.29 |
| 현재 날짜를 열의 기본값으로 사용 (0) | 2023.05.09 |
| 웹팩 5에서 노드 코어 모듈을 폴리필하는 방법 (0) | 2023.05.09 |
| 맥OS에서 Git를 최신 버전으로 업그레이드하는 방법은 무엇입니까? (0) | 2023.05.09 |