결과는 단지 고통스러운 얻을 수있는 이벤트를 구독해야하는 비동기 작업의 전체를 사용하여 단지 시도 할 수 있습니다. 가장 간단한 방법은 이벤트 처리를 멋진 확장 메서드로 추상화하고 결과를 처리하기 위해 연속 통과 스타일 (CPS)을 사용하는 것입니다.
그래서, 우선 다운로드 문자열 확장 메서드를 작성하는 것입니다 :
이
public static void DownloadString(this Uri uri, Action<string> action)
{
if (uri == null) throw new ArgumentNullException("uri");
if (action == null) throw new ArgumentNullException("action");
var webclient = new WebClient();
DownloadStringCompletedEventHandler handler = null;
handler = (s, e) =>
{
var result = e.Result;
webclient.DownloadStringCompleted -= handler;
webclient.Dispose();
action(result);
};
webclient.DownloadStringCompleted += handler;
webclient.DownloadStringAsync(uri);
}
이 방법은 WebClient
의 생성을 멀리 숨기고, 이벤트의 모든 처리 및 처분과 사물을 청소 탈퇴 나중에.
는 그것은 다음과 같이 사용되는 :
var uri = new Uri("http://someplace.com/books.json");
uri.DownloadString(t =>
{
// Do something with the string
});
지금 이것은 GetBooks
방법을 만들 수 있습니다. 여기있다 :
public void GetBooks(Uri uri, Action<List<Books>> action)
{
if (action == null) throw new ArgumentNullException("action");
uri.DownloadString(t =>
{
var books = ParseJSON(t);
action(books);
});
}
는 그것은 다음과 같이 사용되는 : 단정하고 간단해야
this.GetBooks(new Uri("http://someplace.com/books.json"), books =>
{
// Do something with `List<Books> books`
});
.
이제 두 가지 방법으로 확장 할 수 있습니다.
당신이 서명이
ParseJSON
의 과부하 만들 수
:
void ParseJSON(string text, Action<List<Books>> action)
그런 다음 당신이 전부 GetBooks
방법과 멀리 할 수있는 그냥이 쓰기 : 이제
var uri = new Uri("http://someplace.com/books.json");
uri.DownloadString(t => ParseJSON(t, books =>
{
// Do something with `List<Books> books`
// `string t` is also in scope here
}));
당신이 좋은이를 깔끔한 유창한 스타일의 구성 가능한 작업 세트. 보너스로 다운로드 한 문자열 t
도 범위에 있으므로 필요한 경우 쉽게 기록하거나 다른 처리를 할 수 있습니다.
또한 예외를 처리 할 수 있으며, 이들과 같이 추가 할 수 있습니다 : 다음
public static void DownloadString(this Uri uri, Action<string> action)
{
uri.DownloadString(action, null);
}
그리고에 : 당신은 다음과 DownloadString
확장 메서드를 처리되지 않은 오류를 대체 할 수
public static void DownloadString(
this Uri uri,
Action<string> action,
Action<Exception> exception)
{
if (uri == null) throw new ArgumentNullException("uri");
if (action == null) throw new ArgumentNullException("action");
var webclient = (WebClient)null;
Action<Action> catcher = body =>
{
try
{
body();
}
catch (Exception ex)
{
ex.Data["uri"] = uri;
if (exception != null)
{
exception(ex);
}
}
finally
{
if (webclient != null)
{
webclient.Dispose();
}
}
};
var handler = (DownloadStringCompletedEventHandler)null;
handler = (s, e) =>
{
var result = (string)null;
catcher(() =>
{
result = e.Result;
webclient.DownloadStringCompleted -= handler;
});
action(result);
};
catcher(() =>
{
webclient = new WebClient();
webclient.DownloadStringCompleted += handler;
webclient.DownloadStringAsync(uri);
});
}
다음과 같이 오류 처리 방법을 사용하십시오.
var uri = new Uri("http://someplace.com/books.json");
uri.DownloadString(t => ParseJSON(t, books =>
{
// Do something with `List<Books> books`
}), ex =>
{
// Do something with `Exception ex`
});
최종 결과는 사용 및 읽기가 상당히 쉬워야합니다. 이게 도움이 되길 바란다.
무엇을 주위에 감싸고 싶습니까? –
결국에는 GetBooksAsync()라는 비동기 메서드를 갖고 싶습니다. GetBooksCompleted도 가질 수 있습니다. –