Multithreading MonoTouch 6.x中的线程模型更改?

Multithreading MonoTouch 6.x中的线程模型更改?,multithreading,xamarin.ios,Multithreading,Xamarin.ios,虽然晚了几周,但我终于可以用新的6.0版本更新我的MonoTouch iOS应用程序了。对于长时间运行的活动(我的应用程序对后台进行服务调用并上传图像),我使用与示例非常类似的线程。在我升级之前,这一切都非常有效。控制器中的典型模式如下所示: protected void LogInButtonClicked(object sender, EventArgs e) { NetworkActivity.Start(); // start the request.

虽然晚了几周,但我终于可以用新的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(…)上看到了这一点

所以。。。我不确定我到底做错了什么。我确实回去看了一些新的样品。其中一些正在使用任务库(例如),但这不应排除此QueueUserWorkItem方法

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


谢谢。JB

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

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

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

如果你想回到过去的行为,这里有一些说明。但是,请注意,您当前的代码已损坏,虽然它可能在99%的时间内正常工作,但对某些人来说可能会严重损坏(例如,此类问题通常取决于时间,更改代码或使用不同的设备可能会触发此问题)


因此,我强烈建议您像Ben所描述的那样,解决您发现的问题(您的用户会喜欢您的;-)。

或者在调用QueueUserWorkItem之前将其内容复制到局部变量,听起来对我来说是一个更干净的解决方案,IMHO,虽然除非用户编辑速度非常快,否则不会有太大的区别,我也不会称之为线程模型的改变,只是与错误报告相关的错误修复。它基本上是许多UI工具包中的标准模式:您只能从UI的主线程访问与UI相关的属性。如果早期版本允许这样做,那么对我来说这看起来像是一个丢失的错误检查。我现在清楚地看到了这一点。我以前没有考虑过这个问题,没有真正将字段的访问器作为UI线程上下文的一部分。谢谢你说得对,没有太大的线程变化。更多地暴露了我的一个潜在问题。它确实是这样工作的,并且没有崩溃(它实际上非常稳定),但我确实做得不正确:-)只是奇怪的是,它突然中断,以至于我假设线程模式发生了变化。应该只有几个地方我可以这样做,所以应该很容易更新。谢谢哎呀<代码>服务.Login(this.UserName.Text,this.Password.Text)导致问题,因为控件位于UI线程中。只是没有正确思考(这也是较旧的代码;因此从一开始就不正确)。我做了一次代码扫描,当然这是我在排队等待线程后访问UI控件的唯一地方。刚好登录到(!)上。谢谢大家!