SemanticResultValue を利用すると発生する良く分からない例外

System.Speech を使って音声認識を実行するとき、まずは認識する文法 Grammar を生成します。 SemanticResultValue を使って Choices を構成し、そこから生成された Grammar を利用すると、 音声認識の実行時に例外TargetInvocationException (エラー) が通知されることがあります。

この問題は解決されていませんが、記録を残しておきます。 現在取り組んでいることに対して本質的ではないためです。 またいくつか国外のフォーラムについて目を通しましたが、類似する不具合報告はあるものの、 同様不具合やその具体的な解決策は見つけることができませんでした(初回執筆時)。

例外が発生しているパターン

例外が発生しているパターンは次のような状況です。 choices1 の語句に続き choices2 の語句が繋がるような文法を構成します。 ここではセマンティクス値は int 型の変数としています。 (string 型の文字列も許容されているようなので検証しましたがダメでした。)

Choices choices1 = new Choices();
choices1.Add(new SemanticResultValue("赤", 1));
choices1.Add(new SemanticResultValue("青", 2));
choices1.Add(new SemanticResultValue("黄", 3));

Choices choices2 = new Choices();
choices2.Add(new SemanticResultValue("巻紙", 4));

GrammarBuilder grammarBuilder = new GrammarBuilder();
grammarBuilder.Append(choices1);
grammarBuilder.Append(choices2);
grammarBuilder.Culture = recognizerInfo.Culture;

Grammar grammar = new Grammar(grammarBuilder);

この Grammar は SpeechRecognitionEngine に登録し、 実際に音声認識も実行することができます。 ただしchoices2 に登録した語句に対する SpeechHypothesized イベントが実行されるとき、 TargetInvocationException が通知されます。

例外の詳細(次の項目を参照)から分かりますが、"セマンティクス値" について例外が発生しているので、 同じパターンで SemanticResultValue を利用しなければ例外は通知されません。

Choices choices1 = new Choices(new string[] {"赤", "青", "黄"});
Choices choices2 = new Choices(new string[] {"巻紙"});

その他の検証

今回の問題はセマンティクス値の設定とその周辺の動きが良く分からないので、解決できないのだと思います。 とりあえず、同じ Choices に重複するセマンティクス値は設定することができました。 正常に動作しています。

choices1.Add(new SemanticResultValue("青", 2));
choices1.Add(new SemanticResultValue("黄", 3));
choices1.Add(new SemanticResultValue("緑", 3));

また choices2 に SemanticResultValue を利用しないで登録したところ、正常に動作しました。

Choices choices1 = new Choices();
choices1.Add(new SemanticResultValue("赤", 1));
choices1.Add(new SemanticResultValue("青", 2));
…
Choices choices2 = new Choices(new string[] {"巻紙"});

例外の詳細

通知される例外の詳細についてまとめておきます。

通知される例外
TargetInvocationException
呼び出しのターゲットが例外をスローしました。
InnerException
ルール 'root' のセマンティクス値は既に設定されており、変更できません。
Source
System.Speech.Recognition.RecognizedPhrase.InsertSemanticValueToDictionary(割愛)

Reference

msdn の関連する資料では例外の通知についていくつか記述されていますが、 セマンティクス値の活用の方法をきちんと理解できていないと、把握できそうにありません。 また翻訳の精度も上がっていないので、原文(英語)のテキストを参照する必要があります。

msdn と同じ例外の発生

次の下りの箇所に掲載されているサンプルと同じ例外が発生しているのは確認できています。

The following example will cause an exception because it sets and then modifies the root Value of a Grammar.