Xamarin 跨过一个可等待方法

4
在WPF应用程序中,跨越(F10)一个可等待方法会将您带到下一行。但在Xamarin Android项目中,它的行为不同(就像我按下了F5键),我必须在下一行上设置断点才能正确调试——这真是太麻烦了。
 async Task SomeMethod()
 {
     await Task.Delay(1000); <--------- Stepping over this line leaves the function.
     int x = 1; <--------- I have to add a breakpoint here.
 }

这是个问题还是一个特性?

PS:我正在使用Visual Studio 2017。


4
使用Xamarin进行调试时遇到不便的经验通常是一个漏洞。按Shift+F11会导致调试器崩溃,尽管在Mono 5之前这种方法是可用的。如果我是你,我会在bugzilla.xamarin.com上报告它,希望他们能解决它。与普通的WPF应用程序相比,调试确实很麻烦。 - Dbl
这可能是async的一个特性 - 它只是在await操作中超出了方法范围,并在后台继续执行。也许,你应该关闭“仅我的代码”复选框。 - VMAtm
4个回答

0
确保你的方法是异步的。我测试过我的方法,在我的端上可以运行。以下是示例:
  Task.Run(async () =>
      {
        await Task.Delay(1000); 
        int x = 1;
      });

或者

async Task YourMethod
    {
       await Task.Delay(1000); 
       int x = 1;
    }

你使用的是哪个版本的Visual Studio?它是否支持Xamarin Droid? - Akli
最新版本的Visual Studio for Mac是Xamarin Droid。 - Siti

0

很遗憾,这就是 Visual Studio 调试目前的工作方式。由于 Task.Delay() 方法已经被等待,程序流程会返回到调用 YourMethod() 的方法。如果该调用被等待,并且一直向后传递直到达到应用程序上下文的调用链。例如,对于 Xamarin:

例如:

 1 class MyActivity : Activity
 2 {
 3     // This function is called by the Xamarin/Android systems and is not awaited.
 4     // As it is marked as async, any awaited calls within will pause this function,
 5     // and the application will continue with the function that called this function,
 6     // returning to this function when the awaited call finishes.
 7     // This means the UI is not blocked and is responsive to the user.
 8     public async void OnCreate()
 9     {
10         base.OnCreate();
11         await initialiseAsync();  // awaited - so will return to calling function
12                                   // while waiting for operation to complete.
13
14         // Code here will run after initialiseAsync() has finished.
15     }
16     public async Task initialiseAsync()
17     {
18         await YourMethod();  // awaited - so will return to Line 11
19                              // while waiting for operation to complete.
20         
21         // Code here will run after GetNamesAsync() has finished.
22     }
23 }

在纯Windows应用程序中,Visual Studio了解应用程序的上下文,并知道底层方法(程序生命周期、窗口事件、屏幕重绘等)不需要调试(源代码也无法访问)。您可能看到的是调试器暂停1000毫秒,因为没有要调试的代码。
Xamarin添加了一个额外的代码层,包括基本Activity类的实现和所有Android要求。Visual Studio不知道跳过这些内容,因此尝试调试调用当前等待堆栈方法的任何代码。这可能是像基本Activity类的OnCreate()方法之类的东西,您可能无法访问该代码。

0

这就是await运算符的工作原理。当你await一个Task时,代码执行将跳出当前函数并将控制权交给其调用者。然后,在稍后的某个时间点,当等待的Task完成后,它将跳回到await语句之后执行代码。

如果你跨过一个await,调试器会导航到下一行即将执行的代码。在await的情况下,它很可能不会是下一行。


5
请尝试在 WPF、Windows Forms 或者 Windows Phone 中运行此代码,按 F10 可以跳转到“int x=1”,但是如果在 Xamarin.Forms 或 Android 中尝试,则无法跳转。注意,翻译时需保持原意,使内容易于理解,不得添加解释或其他额外内容。 - Akli
@voytasify 这不是 await 的工作方式。await 会立即执行使用 await 关键字调用的方法并执行方法内部的代码。只有在被调用方法中(或其被调用的方法中)调用其他(通常是 I/O 绑定的)操作以等待它们自己的结果(通过调用带有 await 的方法或返回 Task),当前线程才可能被调度程序重新分配一段时间。因此,进入等待的方法应该总是有效的,跳过等待的方法也应该如此。 - lauxjpn

0

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接