You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Xamarin.iOS中Async/Await场景下PerformSegue失效问题求助

分析与解决方案

首先,咱们先拆解你遇到的问题:在异步事件处理方法里调用PerformSegue没反应,但同步调用就正常,试过主线程调度也没用。我遇到过类似的情况,大概率是这几个原因:

1. Async Void 导致的异常静默丢失

你用的async private void作为事件处理方法,这种写法虽然符合事件签名,但有个致命问题:如果InvokeApiAsync抛出异常,这个异常会直接被.NET Runtime吞掉(不会冒泡到调用栈),导致你的if (searchItemsResult != null)代码块根本没执行!

验证方法

给你的异步方法加个try-catch,看看是不是API调用抛出了异常:

async private void SearchButton_TouchUpInside(object sender, EventArgs e) {
    try {
        var dictionary = new Dictionary<string, string> { {"searchText", "abc" } }; 
        searchItemsResult = await client.InvokeApiAsync<items>("search/searchitems", HttpMethod.Get, dictionary); 
        if (searchItemsResult != null) { 
            Console.WriteLine("准备执行Segue"); // 加个日志确认走到这里了
            InvokeOnMainThread(() => {
                this.PerformSegue("vC2Segue", this); 
            });
        }
    } catch (Exception ex) {
        Console.WriteLine($"API调用出错:{ex.Message}");
    }
}

如果控制台输出了异常信息,那就是这个问题——你之前以为API返回了结果,其实是调用失败了,代码根本没走到PerformSegue那一步。

2. Segue 配置的隐性错误

虽然你移除async/await后能正常跳转,但还是要再确认一遍:

  • 检查Storyboard里的segue标识符是不是完全匹配"vC2Segue"(大小写敏感!)
  • 确认segue是从当前ViewController直接连到目标ViewController,而不是从按钮直接连的(如果是按钮直接连的segue,点击按钮会自动触发,和你的代码逻辑冲突)

3. 主线程调度的正确姿势

你之前的代码里注释了两种主线程调度方式,但可能没正确包裹或者存在上下文问题。试试用BeginInvokeOnMainThread(Xamarin.iOS专用的主线程调度方法),并且确保调用时当前ViewController是活跃状态:

if (searchItemsResult != null) { 
    BeginInvokeOnMainThread(() => {
        if (this.IsViewLoaded && this.View.Window != null) { // 确认VC处于活跃状态
            this.PerformSegue("vC2Segue", this); 
        }
    });
}

更健壮的写法建议

把异步逻辑抽成单独的async Task方法,这样更容易管理异常和调试:

public override void ViewDidLoad() { 
    base.ViewDidLoad(); 
    searchButton.TouchUpInside += async (s, e) => await HandleSearchAsync(); 
} 

private async Task HandleSearchAsync() {
    try {
        var dictionary = new Dictionary<string, string> { {"searchText", "abc" } }; 
        searchItemsResult = await client.InvokeApiAsync<items>("search/searchitems", HttpMethod.Get, dictionary); 
        if (searchItemsResult != null) { 
            BeginInvokeOnMainThread(() => {
                this.PerformSegue("vC2Segue", this); 
            });
        }
    } catch (Exception ex) {
        // 这里可以弹个Alert提示用户搜索失败
        BeginInvokeOnMainThread(() => {
            var alert = UIAlertController.Create("错误", "搜索失败,请稍后重试", UIAlertControllerStyle.Alert);
            alert.AddAction(UIAlertAction.Create("确定", UIAlertActionStyle.Default, null));
            PresentViewController(alert, true, null);
        });
    }
}

先按这个步骤排查,最可能的就是异步方法里的异常没被捕获,导致代码没执行到PerformSegue。如果还是不行,可以再检查下当前ViewController是否被UINavigationController托管(如果你的Segue是push类型的话,必须在导航栈里)。

内容的提问来源于stack exchange,提问作者John D

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.13 08:38:50