3

几个星期后,但我终于回来用新的 6.0 版本更新我的 MonoTouch iOS 应用程序。对于长时间运行的活动(我的应用程序对后台进行服务调用并进行图像上传),我使用与示例非常相似的线程。在我升级之前,这一切都很好。控制器中的典型模式如下所示:

protected void LogInButtonClicked(object sender, EventArgs e)
{
      NetworkActivity.Start();

      // start the request.
      ThreadPool.QueueUserWorkItem ((cb) => {

          var service = new ClientUserService();
          var result = service.Login(this.UserName.Text, this.Password.Text);

          // when done, switch back to UI.
          this.InvokeOnMainThread (() => {

              NetworkActivity.Stop();

              // do the various other things to init the app on the UI thread.
          }
      });
}

在 5.x 上运行良好并且从未崩溃。它遵循已发布的代码指南。但是现在我立即得到了 UUIKit 一致性错误的异常:您正在调用只能从 UI 线程调用的 UIKit 方法。我在我的服务热线 (service.Login(...)) 上得到了它。

所以......我不确定我在这里做错了什么。我确实回去查看了一些较新的样本。其中一些正在使用任务库(例如https://github.com/xamarin/mobile-samples/blob/master/MultiThreading/iOSMultiThreading/Screens/MainScreen_iPhone.cs),但这不应排除此 QueueUserWorkItem 方法。

问题:Monotouch 中的线程模型是否发生了重大变化,从而不再支持上述编码模式?

谢谢。JB

4

2 回答 2

6

将 this.UserName.Text 和 this.Password.Text 包装在 InvokeOnMainThread 委托中。Monotouch 期望 UI 元素的所有工作都在 UI 线程中执行。

于 2012-12-01T03:39:15.353 回答
3

此功能是不久前在MonoTouch 5.4中引入的(请参阅新库功能,跨线程 UI 检查)。

现在这不是线程更改(代码像以前一样执行),而只是额外的检查,以确保人们被警告一个常见的陷阱——这通常很难调试。

如果您想恢复旧的行为,有说明。但是请注意,您当前的代码已损坏,虽然它可能在 99% 的时间内都可以正常工作,但对某些人来说可能会严重损坏(例如,此类问题通常与时间相关,更改代码或使用不同的设备可能会触发该问题)。

因此,我强烈建议您在发现问题时解决这些问题(您的用户会因此而爱上您 ;-),就像 Ben 所描述的那样。

于 2012-12-01T15:12:40.137 回答