Bug 9657 - UIView.StringSize calls EnsureUIThread
Summary: UIView.StringSize calls EnsureUIThread
Alias: None
Product: iOS
Classification: Xamarin
Component: General ()
Version: 6.0.x
Hardware: Macintosh Mac OS
: --- normal
Target Milestone: Untriaged
Assignee: Bugzilla
Depends on:
Reported: 2013-01-17 14:25 UTC by Adam Patridge
Modified: 2013-01-22 10:41 UTC (History)
3 users (show)

Is this bug a regression?: ---
Last known good build:

Notice (2018-05-24): bugzilla.xamarin.com is now in read-only mode.

Please join us on Visual Studio Developer Community and in the Xamarin and Mono organizations on GitHub to continue tracking issues. Bugzilla will remain available for reference in read-only mode. We will continue to work on open Bugzilla bugs, copy them to the new locations as needed for follow-up, and add the new items under Related Links.

Our sincere thanks to everyone who has contributed on this bug tracker over the years. Thanks also for your understanding as we make these adjustments and improvements for the future.

Please create a new report on Developer Community or GitHub with your current version information, steps to reproduce, and relevant error messages or log files if you are hitting an issue that looks similar to this resolved bug and you do not yet see a matching new report.

Related Links:

Description Adam Patridge 2013-01-17 14:25:14 UTC
Since one could code directly to NSString.StringSize on a non-UI thread, it seems that the call to EnsureUIThread in UIView.StringSize may be unnecessarily restrictive to calling code (either that or NSString.StringSize should have it, too, if there is some UI-based magic involved with string measurements). I do appreciate the convenience of having it on UIView, but I was curious if the UI restriction was actually needed there.

Doesn't work:

    Task.Factory.StartNew(() => {
        // Blows up discretely...nothing written to application output.
        SizeF textSize = someView.StringSize(someString, someFont, new SizeF(someView.Bounds.Width, float.MaxValue), UILineBreakMode.WordWrap);

Does work (it has since been pointed out I probably shouldn't hit Bounds in non-UI thread either, though):

    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);
Comment 1 Sebastien Pouliot 2013-01-17 19:49:40 UTC
ref: http://stackoverflow.com/q/14385826/220643

As far as I know the `Bounds` property is thread-safe (and marked as such in MonoTouch). Apple is not 100% clear on it but some of it's samples, that shows API available in multi-threaded scenarios, are using it (and would not be usable without it).

Also your `someFont` is an UIFont (from UIKit too) but "Using color and font objects in multiple threads is now safe to do." [1]

So I _believe_ StringSize should be safe. We'll have a deeper look and, if it looks right, will mark is as [ThreadSafe] in future releases of MonoTouch.

[1] http://developer.apple.com/library/ios/#releasenotes/General/WhatsNewIniPhoneOS/Articles/iPhoneOS4.html
Comment 2 Sebastien Pouliot 2013-01-22 10:37:30 UTC
We already detremined that DrawString (drawInRect:* selectors) were fine from other threads. StringSize is a subset of that feature so it should be safe to. Future versions (6.0.10+) will be marked as [ThreadSafe].

Thanks for the report.

master: eb044075970f7df6b4f6382a975dd388f969d4d5
ios6: 9164dff7c0d0e5563c593441ef76e10adb2e459d
Comment 3 Miguel de Icaza [MSFT] 2013-01-22 10:41:50 UTC
Reading Bounds might be thread safe, but setting Bounds is not likely thread safe.