C# Tak.Run ContinueWith无法在android上更新UI

C# Tak.Run ContinueWith无法在android上更新UI,c#,android,xamarin,asynchronous,task,C#,Android,Xamarin,Asynchronous,Task,您好,我有一个xamarin with cocossharp项目,我尝试使用任务。运行,但UI更新仅在iOS上运行 这是我的密码 await Task.Run(async () => { await UserService.InitLoadOtherPlayerResoucres(); }).ContinueWith(a => { PlayerTwoFinal = UserService.OtherPlayersProfile; PlayerTwoFinal.

您好,我有一个xamarin with cocossharp项目,我尝试使用
任务。运行
,但UI更新仅在iOS上运行

这是我的密码

await Task.Run(async () =>
{
    await UserService.InitLoadOtherPlayerResoucres();
}).ContinueWith(a =>
{
    PlayerTwoFinal = UserService.OtherPlayersProfile;
    PlayerTwoFinal.ContentSize = new CCSize(PlayerTwo.ContentSize.Width,
        PlayerTwo.ContentSize.Height);
    PlayerTwoFinal.Position = new CCPoint(PlayerTwo.PositionX, PlayerTwo.PositionY);
    Player2.AddChild(PlayerTwoFinal, 0);
    Debug.WriteLine(">>>>> LOAD ORIGINAL IMAGE COMPLETE");
});
我尝试了
Task.Factory.StartNew
,但没有成功

这是
UserService.initLoadOtherPlayerResoures()的代码。

ContinueWith()
不一定会在UI线程上执行代码

有一种方法可以用来强制
ContinueWith()
使用UI线程,但实际上应该是完全异步的:

var a = await UserService.InitLoadOtherPlayerResoucres();

PlayerTwoFinal = UserService.OtherPlayersProfile;
PlayerTwoFinal.ContentSize = new CCSize(PlayerTwo.ContentSize.Width, PlayerTwo.ContentSize.Height);
PlayerTwoFinal.Position = new CCPoint(PlayerTwo.PositionX, PlayerTwo.PositionY);
Player2.AddChild(PlayerTwoFinal, 0);
Debug.WriteLine(">>>>> LOAD ORIGINAL IMAGE COMPLETE");
通过使用
wait
可以确保用户界面线程在
UserService.initLoadOtherPlayerResoures()执行时保持可用

使用
Task.Run
也是多余的,只会增加开销


根据修改后的问题进行更新

尽管
InitLoadOtherPlayerResoucres
已使用
async
关键字修饰,但它实际上根本不是异步的,因此无论是否等待它,它都将被阻塞

理想情况下,您应该重新编写
initLoadOtherPlayerResoures
,使其真正异步,这将确保在异步工作完成时释放UI线程

调用
GetByteArrayAsync().Result
.Result
将阻止线程,直到由
GetByteArrayAsync()
生成的
任务完成。相反,这应该是:

var streamImage = await webClient.GetByteArrayAsync(OtherPlayersUserPhoto);
ContinueWith()
不一定会在UI线程上执行代码

有一种方法可以用来强制
ContinueWith()
使用UI线程,但实际上应该是完全异步的:

var a = await UserService.InitLoadOtherPlayerResoucres();

PlayerTwoFinal = UserService.OtherPlayersProfile;
PlayerTwoFinal.ContentSize = new CCSize(PlayerTwo.ContentSize.Width, PlayerTwo.ContentSize.Height);
PlayerTwoFinal.Position = new CCPoint(PlayerTwo.PositionX, PlayerTwo.PositionY);
Player2.AddChild(PlayerTwoFinal, 0);
Debug.WriteLine(">>>>> LOAD ORIGINAL IMAGE COMPLETE");
通过使用
wait
可以确保用户界面线程在
UserService.initLoadOtherPlayerResoures()执行时保持可用

使用
Task.Run
也是多余的,只会增加开销


根据修改后的问题进行更新

尽管
InitLoadOtherPlayerResoucres
已使用
async
关键字修饰,但它实际上根本不是异步的,因此无论是否等待它,它都将被阻塞

理想情况下,您应该重新编写
initLoadOtherPlayerResoures
,使其真正异步,这将确保在异步工作完成时释放UI线程

调用
GetByteArrayAsync().Result
.Result
将阻止线程,直到由
GetByteArrayAsync()
生成的
任务完成。相反,这应该是:

var streamImage = await webClient.GetByteArrayAsync(OtherPlayersUserPhoto);

谢谢@jonathan的回复,我想做的是等待UserService.initLoadOtherPlayerResoures();在运行其他代码之前首先执行或完成,因为资源将通过运行UserService.initLoadOtherPlayerResoures()提供;但不影响UI@JanGenvherPapica这正是将要发生的事情。当您点击
wait
时,当前线程将被释放,方法的其余部分将被安排在
UserService.initLoadOtherPlayerResoures()完成后恢复。Xamarin
SynchronizationContext
将确保在UI线程上恢复该方法。我在Johnathan使用了该代码,但在UI再次工作之前,应用程序仍会冻结3-5秒。这意味着它仍在等待等待UserService.InitLoadOtherPlayerResoucres();成为finished@JanGenvherPapica你能发布你的
UserService.initLoadOtherPlayerResoures
方法吗?这可能会造成阻塞。@JanGenvherPapica请参阅更新。您的
initloadotherplayerresoures
当前不是
async
,将被阻止。感谢@jonathan的回复,我想做的是等待UserService.initloadotherplayerresoures();在运行其他代码之前首先执行或完成,因为资源将通过运行UserService.initLoadOtherPlayerResoures()提供;但不影响UI@JanGenvherPapica这正是将要发生的事情。当您点击
wait
时,当前线程将被释放,方法的其余部分将被安排在
UserService.initLoadOtherPlayerResoures()完成后恢复。Xamarin
SynchronizationContext
将确保在UI线程上恢复该方法。我在Johnathan使用了该代码,但在UI再次工作之前,应用程序仍会冻结3-5秒。这意味着它仍在等待等待UserService.InitLoadOtherPlayerResoucres();成为finished@JanGenvherPapica你能发布你的
UserService.initLoadOtherPlayerResoures
方法吗?这可能会造成阻塞。@JanGenvherPapica请参阅更新。您的
initLoadOtherPlayerResources
当前不是
async
,将被阻止。