「エキサイト公式プラチナブロガー」スタート!
.NET4.5におけるasync/awaitを使用した非同期処理
VS2012以降で.NET4.5をターゲットにした場合,async/awaitを使用した非同期処理を使用できる

サンプルコード

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Net.Http;

namespace AsyncSample
{
class Program
{

static void Main(string[] args)
{
Console.WriteLine("Main...");
Task t = Test();
Console.WriteLine("Main...Wait");
t.Wait();
Console.WriteLine("Main...Wait/end");
Console.ReadLine();
}

static async Task Test()
{
Console.WriteLine("Test...");
int length = await AccessTheWebAsync();
Console.WriteLine("Test..." + length.ToString());
return;
}

static async Task<int> AccessTheWebAsync()
{
Console.WriteLine("AccessTheWebAsync()");
// You need to add a reference to System.Net.Http to declare client.
HttpClient client = new HttpClient();

// GetStringAsync returns a Task<string>. That means that when you await the
// task you'll get a string (urlContents).
Task<string> getStringTask = client.GetStringAsync("http://msdn.microsoft.com");

// You can do work here that doesn't rely on the string from GetStringAsync.
DoIndependentWork();

// The await operator suspends AccessTheWebAsync.
// - AccessTheWebAsync can't continue until getStringTask is complete.
// - Meanwhile, control returns to the caller of AccessTheWebAsync.
// - Control resumes here when getStringTask is complete.
// - The await operator then retrieves the string result from getStringTask.
Console.WriteLine("AccessTheWebAsync()... await getStringTask");
string urlContents = await getStringTask;
Console.WriteLine("AccessTheWebAsync()... await getStringTask End");

// The return statement specifies an integer result.
// Any methods that are awaiting AccessTheWebAsync retrieve the length value.
return urlContents.Length;
}

static void DoIndependentWork()
{
Console.WriteLine("DoIndependentWork();");
}
}
}



実行結果

Main...
Test...
AccessTheWebAsync()
DoIndependentWork();
AccessTheWebAsync()... await getStringTask
Main...Wait
AccessTheWebAsync()... await getStringTask End
Test...25204
Main...Wait/end


解説
メソッドについているasyncは非同期を表す修飾子。この戻り値はvoidまたはTaskになる。
http://msdn.microsoft.com/ja-jp/library/hh156513.aspx
戻り値を返したい場合,Task<戻り値の型>となる。

メソッドを呼び出す際に指定している await 演算子は、待機中のタスクが完了するまでメソッドの実行を中断する。
http://msdn.microsoft.com/ja-jp/library/hh156528.aspx

Test() メソッド中にAccessTheWebAsyncメソッドをasyncをつけて読んでいるが、これは、AccessTheWebAsyncの処理が終了するまで
待機することを表す。
awaitを用いて中断している場合は、呼び出し元に制御を返し、処理が完了したら中断している箇所から制御が再開する。

Wait()も制御を中断するが、呼び出し元に制御がもどることはない。
たとえば、以下のコードを置き換える

//int length = await AccessTheWebAsync();
Task<int> t = AccessTheWebAsync();
t.Wait();
int length = t.Result;

この場合の実行結果は以下のようになり、Mainに制御がもどらずに、Test()中で中断していることがわかる。

Main...
Test...
AccessTheWebAsync()
DoIndependentWork();
AccessTheWebAsync()... await getStringTask
AccessTheWebAsync()... await getStringTask End
Test...25204
Main...Wait
Main...Wait/end


なお、VS2012以降(C#5.0)なら.NET4.5以外をターゲットにしてもasync/awaitを使用した非同期処理を使用できる。
http://xin9le.net/articles/81

参考
http://msdn.microsoft.com/ja-jp/library/hh191443.aspx

[PR]
# by mima_ita | 2014-07-02 00:46 | .NET
.NETでTwitterを検索する
目的
.NETを用いてTwitterの検索を行う。

環境
Windows7
VisualStudio Express 2013 for Windows DeskTop

LINQ to Twitter
LINQ to TwitterはLINQを用いてTwitterの操作を行える。
http://linqtotwitter.codeplex.com/

このライブラリSystem.Net.Http.Primitivesに依存しているので、以下のようにインストールすること。

1. プロジェクトの参照設定でNuGetパッケージの管理を選択する
b0232065_00401670.png
2.Microsoft HTTP Client Libraryをインストールする
b0232065_00405023.png
AccessTokenとAccessTokenSecretの取得方法
クライアントアプリケーションでAccessTokenとAccessTokenSecretを取得するには次のように認証用のURLを開いて、PINコードを取得して、それを使用して認証を行う。

C#でOAuthでTwitter 
http://d.hatena.ne.jp/nojima718/20100129/1264792636

なお、CONSUMERKEY,CONSUMERSECRETはTwitterDeveloperでアプリケーションを追加してキーを発行する。
https://dev.twitter.com/

LINQ to Twitterでツイートを検索する

var singleAuth = new SingleUserAuthorizer
{
CredentialStore = new SingleUserInMemoryCredentialStore
{
ConsumerKey = this.auth.ConsumerKey,
ConsumerSecret = this.auth.ConsumerSecret ,
AccessToken = this.auth.AccessToken ,
AccessTokenSecret = this.auth.AccessTokenSecret
}
};
var str = "";

var twitterCtx = new TwitterContext(singleAuth);
var searchResponse =
await
(from search in twitterCtx.Search
where search.Type == SearchType.Search &&
search.Query == txtSearch.Text &&
search.Count == 100
select search)
.SingleOrDefaultAsync();

if (searchResponse != null && searchResponse.Statuses != null)
searchResponse.Statuses.ForEach(tweet =>
str += String.Format("CreatedAt: {0}, User: {1}, Tweet: {2}\r\n",
tweet.CreatedAt,
tweet.User.ScreenNameResponse,
tweet.Text));

txtLog.Text = str;


[PR]
# by mima_ita | 2014-06-29 00:49 | .NET
Redmineのプラグインでログを残したい場合
Redmineのプラグインのデバッグでログを残したい場合は次のようにすればよい。

Rails.logger.info "executing command: #{out['command']}"

下記のファイルにログが出力される。
/var/lib/redmine/log/production.log

[PR]
# by mima_ita | 2014-06-28 03:29 | ruby
IO.popenのwriteのエンコードが正常に動作しない場合
次のようなコードがあったとする。

# coding: utf-8
msg = "Alice->Bob: あiいいあああ\n"
c = nil
IO.popen
('/usr/bin/plantuml -pipe', 'r+b'){|f|
f.puts '@startuml'
f.write msg
f.write '@enduml'
f.close_write
c = f.read
}

この際、UTF-8の文字をいくらwriteしても正常にわたらない場合がある。
この場合、Encoding.find("locale")の値を確認してみる。

もし、UTF-8になっていなければ、いくらinternal_encodingやexternal_encodingをいじっても正常に動作しない。


[PR]
# by mima_ita | 2014-06-28 03:25 | ruby
RedmineのWikiでUMLを記述する方法
目的
RedmineのWikiにシーケンス図やユースケースなどのUMLを記述する。

前提:
JAVAが動くこと
Redmineが動作すること
Apache2でRedmineが動いていたものとする

手順:

1. PlantUMLを下記よりダウンロードして任意のフォルダにおく
http://plantuml.sourceforge.net/download.html

 この例では下記にあるとする.
 /share/plantuml.jar

2. ラッパー用のシェルスクリプトを記述する。
 この例では/usr/bin/plantuml に記述するものとする。


#!/bin/bash
/usr/bin/java -Djava.io.tmpdir=/var/tmp -jar /share/plantuml.jar ${@}



3. Redmine用のプラグインを下記からダウンロードする
https://github.com/cdwertmann/wiki_external_filter

4. 3のファイルをRedmineのプラグインにコピーする。
この際,フォルダ名はwiki_external_filterとする。
デフォルトはwiki_external_filter_masterになっており、名前が違うと正常に動作しない

例:/var/lib/redmine/plugins/wiki_external_filter

5. 下記に書き込み権限を与える。
 /var/lib/redmine/public/plugin_assets/

例:
chmod go+w /var/lib/redmine/public/plugin_assets/

6. 解凍したディレクトリに存在するconfig/wiki_external_filter.yml を redmineのconfigにコピーする。
 例:
  /var/lib/redmine/config
 
7. wiki_external_filter.ymlのplantumlにおけるパスを適切に指定する。
 ※この例だと修正不要のはず

8. apache2の起動時のlocaleをutf-8とする。
 これを怠ると、日本語が適切に表示されなくなる。
 /etc/apache2/envvars の下記を修正
 export LANG=ja_JP.UTF-8
 
 なお、下記の戻り値がUTF-8ならば日本語が使えるようになる。
 Encoding.find("locale")

9. apache2を再起動

10.redmineの管理メニューより、キャッシュの保持時間を指定する。
  デフォルトは0であるが、この場合は、キャッシュを保持せず画像が絶対に表示されない。

  管理>プラグイン>Wiki External Filter Plugin の設定

  「Cache expiration time 」に十分大きな数値を入力
b0232065_03141636.png


11. 下記のような文章をWikiに記述する

{{plantuml
ジョニー-> ジャック: 求愛
ジャック-> サラ: 求愛
サラ->ジョニー: 求愛

}}

b0232065_03143326.png


[PR]
# by mima_ita | 2014-06-28 03:16 | memo



実験ですお
検索
カテゴリ
最新の記事
.NET4.5におけるasy..
at 2014-07-02 00:46
.NETでTwitterを検..
at 2014-06-29 00:49
Redmineのプラグインで..
at 2014-06-28 03:29
IO.popenのwrite..
at 2014-06-28 03:25
RedmineのWikiでU..
at 2014-06-28 03:16
以前の記事
最新のトラックバック
人気ジャンル
ブログパーツ