UIView.StringSize
のような非同期コード内から実行すると、そのメソッドはto (MonoDevelopの「Gotodeclaration」。ライセンスでここに投稿できるかどうかわかりません)の呼び出しで始まるため、Task.ContinueWith
爆発します。UIKitThreadAccessException
UIApplication.EnsureUIThread
Task.Factory.StartNew(() => {
// Blows up discretely...nothing written to application output.
// Also blows up for UIViews that exist only in code (not rendered).
SizeF textSize = someView.StringSize(someString, someFont, new SizeF(someView.Bounds.Width, float.MaxValue), UILineBreakMode.WordWrap);
Console.WriteLine(textSize);
});
この簡略化されたバージョンをでラップするとInvokeOnMainThread
、すべてがうまくいきますが、その呼び出しなしでテキストを測定したい場合があります。同様に、私は例外の目的を完全に理解しており、以前に非同期コードの奥深くで何かを呼び出したときに多くの手間を省きましたが、この場合、EnsureUIThread
ここでの使用は不要のようです。その呼び出しをNSString
クラスのヒットとして単純に言い換えると、UIスレッドの外で問題なく実行されます。
Task.Factory.StartNew(() => {
// Outputs expected size data: "{Width=##, Height=##}".
using (NSString nssSomeString = new NSString(someString)) {
SizeF textSize = nssSomeString.StringSize(someFont, new SizeF(someView.Bounds.Width, float.MaxValue), UILineBreakMode.WordWrap);
Console.WriteLine(textSize);
}
});
のコードUIView.StringSize
はほぼ同じNSString
作業を行うようであり、UIスレッド指向の露骨なものは何もないようです。このバージョンのメソッドをUIスレッドから呼び出す必要がある何かが欠けていますか?
編集(2013-01-17):
Xamarinにバグを報告して、彼らの応答を確認しました。このメソッドをとしてマークすることを検討しているようThreadSafe
です。