Skip to content

Instantly share code, notes, and snippets.

@biac
biac / FeedReader.cs
Created Dec 6, 2011
FeedReader: 並列処理の実装
View FeedReader.cs
public async Task<IList<FeedData>> ReadAsync(string[] feedUrlStrings)
{
List<Task<FeedData>> taskList = new List<Task<FeedData>>(feedUrlStrings.Length);
// タスク開始のループ
foreach (string url in feedUrlStrings)
taskList.Add(this.ReadAsync(url));
List<FeedData> result = new List<FeedData>(feedUrlStrings.Length);
// タスクから結果を取り出すループ
foreach (Task<FeedData> task in taskList)
@biac
biac / FeedReader.cs
Created Dec 6, 2011
FeedReader: 非同期実行中の例外をシミュレートする仕掛け
View FeedReader.cs
public class FeedReader
{
#if DEBUG
public string test__RaiseErrorUrl;
public Exception test__RaiseException;
#endif
// (略)
private async Task<FeedData> ReadAsync(Uri feedUri)
@biac
biac / FeedReaderTests.cs
Created Dec 6, 2011
FeedReader: 非同期実行中に発生した例外を捕まえるテスト
View FeedReaderTests.cs
#if DEBUG
[TestMethod]
public void ReadAsync2Test2_フィード取得中に例外発生()
{
FeedReader fd = new FeedReader() {
test__RaiseErrorUrl = RssUrls[2],
test__RaiseException = new System.Net.WebException("ユニットテスト用の例外シミュレート")
};
Task<IList<FeedData>> task = fd.ReadAsync(RssUrls);
@biac
biac / FeedReader.cs
Created Dec 7, 2011
FeedReader: 並列処理の実装 (gist:1437510の改良版)
View FeedReader.cs
public async Task<IList<FeedData>> ReadAsync(string[] feedUrlStrings)
{
IEnumerable<Task<FeedData>> readAsyncTasks = feedUrlStrings.Select(
url => this.ReadAsync(url)
);
return (await Task.WhenAll(readAsyncTasks));
}
//参考: http://download.microsoft.com/download/5/B/9/5B924336-AA5D-4903-95A0-56C6336E32C9/TAP.docx
View LongTimeLogicSample.cs
public class LongTimeLogicSample
{
public static int LongTimeMethod(int n)
{
// このロジックは、処理に長い長~い時間が掛かるのだと思ってくれ。
// だけどこのメソッドは普通に書いてあって、非同期処理なんて考えてないものとする。
Thread.Sleep(3000);
return n * 2;
}
@biac
biac / LongTimeLogicSample.cs
Created Dec 9, 2011
LongTimeMethodAsync()
View LongTimeLogicSample.cs
public static Task<int> LongTimeMethodAsync(int n)
{
return Task.Run<int>(() => LongTimeMethod(n));
//Run() は .NET Framework 4.5 から。 4.0 の StartNew() を使った以下のコードと同じ。
//return Task.Factory.StartNew<int>(
// () => LongTimeMethod(n),
// CancellationToken.None,
// TaskCreationOptions.DenyChildAttach,
// TaskScheduler.Default
View SamplePage.xaml.cs
private async void Button1_Click(object sender, RoutedEventArgs e)
{
int input = this.InputValue;
this.OutputValue = (await LongTimeLogicSample.LongTimeMethodAsync(input)).ToString("000");
}
@biac
biac / LongTimeLogicSample.cs
Created Dec 9, 2011
LongTimeMethodAsync() キャンセル可能バージョン
View LongTimeLogicSample.cs
public static Task<int> LongTimeMethodAsync(int n, CancellationToken token)
{
return Task.Factory.StartNew<int>(() => LongTimeMethod(n, token), token);
}
@biac
biac / LongTimeLogicSample.cs
Created Dec 9, 2011
LongTimeMethod() キャンセル可能バージョン
View LongTimeLogicSample.cs
public static int LongTimeMethod(int n, CancellationToken token)
{
// このロジックは、処理に長い長~い時間が掛かるのだと思ってくれ。
Thread.Sleep(1000);
// 非同期実行中のキャンセルを実現するには、ロジックも改造する必要がある。
if (token.IsCancellationRequested)
{
token.ThrowIfCancellationRequested();
@biac
biac / LongTimeLogicSampleTests.cs
Created Dec 9, 2011
キャンセル可能な Async メソッドの使い方
View LongTimeLogicSampleTests.cs
[TestMethod]
public void LongTimeMethodAsyncTest2_CancellationToken付き()
{
Stopwatch sw = Stopwatch.StartNew();
CancellationTokenSource cts = new CancellationTokenSource();
Task<int> task = LongTimeLogicSample.LongTimeMethodAsync(1, cts.Token);
sw.Stop();
//Assert.AreEqual<long>(0, sw.ElapsedMilliseconds);