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

如何从C# Task中返回int值?WinForms异步开发技术求助

如何从异步Task中返回int值并更新WinForms GUI

我已通过异步编程实现了不阻塞WinForms GUI的函数,现在需要解决的问题是:如何从Task中返回int值,并用这些值更新GUI对应的变量(比如currentMana和currentReadiness)。相关代码如下:

MainUI.cs

private void button_StartStop_Click(object sender, EventArgs e)
{
     if (!Profile.ProfileLoaded)
     {
         return;
     }

     if (!UABA.Status)
     {
         button_StartStop.BackgroundImage = ((Image)(Properties.Resources.Stop_Button));
         UABA.Status = true;
         Task.Run(() => Main.RunAsync(this));
     }
     else
     {
         button_StartStop.BackgroundImage = ((Image)(Properties.Resources.Play_Button));
         UABA.Status = false;
     }
}

Main.cs

public static async Task RunAsync(MainUI form_mainUI)
{
    while (true)
    {                
        if (UABA.Status)
        {
            await Task.Run(() => GameData.GetCharacterWindowInformationAsync());
        
            UI.GameData.Character.UpdateCurrentManaValue();
            UI.GameData.Character.UpdateCurrentReadiness();                                     
        }
    }
}

GameData.cs

public static async Task GetCharacterWindowInformationAsync()
{
    List<Task<int>> tasks = new List<Task<int>>();

    if (MonitorMana.MonitoringManaBar)
    {
        var gameData = new GameData();         
        tasks.Add(Task.Run(() => gameData.ReadPixelsInALineAsync()));
    }
    if (MonitorReadiness.MonitoringReadinessBar)
    {
        var gameData = new GameData();
        tasks.Add(Task.Run(() => gameData.GetCurrentReadiness()));
    }

    await Task.WhenAll(tasks);     

    //等待完成后,我希望使用每个Task返回的int值更新GUI所用的不同变量(如currentMana和currentReadiness)。      
}

public Task<int> ReadPixelsInALineAsync()
{
    //Do Work Here

    return Task.FromResult(resultOfSomeWork);
}

解决方案

要获取Task返回的int值并更新对应变量,你可以通过以下方式实现:

  1. 单独跟踪每个任务,明确结果对应关系
    不要把所有任务都放进同一个List<Task<int>>,而是分别声明变量存储每个任务,这样就能直接区分哪个结果对应mana,哪个对应readiness:

    // 修改GameData.cs中的GetCharacterWindowInformationAsync方法
    public static async Task GetCharacterWindowInformationAsync(MainUI form)
    {
        Task<int> manaTask = null;
        Task<int> readinessTask = null;
    
        if (MonitorMana.MonitoringManaBar)
        {
            var gameData = new GameData();         
            manaTask = Task.Run(() => gameData.ReadPixelsInALineAsync());
        }
        if (MonitorReadiness.MonitoringReadinessBar)
        {
            var gameData = new GameData();
            readinessTask = Task.Run(() => gameData.GetCurrentReadiness());
        }
    
        // 等待所有任务完成
        await Task.WhenAll(manaTask, readinessTask);
    
        // 处理返回值并更新UI(注意:WinForms控件必须在UI线程更新)
        if (manaTask != null)
        {
            int currentMana = manaTask.Result; // 任务已完成,直接取Result安全
            // 通过UI实例调用线程安全的更新方法
            form.UpdateMana(currentMana);
        }
        if (readinessTask != null)
        {
            int currentReadiness = readinessTask.Result;
            form.UpdateReadiness(currentReadiness);
        }
    }
    
  2. 添加UI线程安全的更新方法
    在MainUI.cs中添加线程安全的UI更新方法,确保控件操作在UI线程执行:

    public void UpdateMana(int value)
    {
        if (InvokeRequired)
        {
            Invoke(new Action<int>(UpdateMana), value);
            return;
        }
        // 这里替换成你的实际UI控件更新逻辑
        // 例如:label_Mana.Text = $"当前 mana: {value}";
        UI.GameData.Character.CurrentMana = value;
        UI.GameData.Character.UpdateCurrentManaValue();
    }
    
    public void UpdateReadiness(int value)
    {
        if (InvokeRequired)
        {
            Invoke(new Action<int>(UpdateReadiness), value);
            return;
        }
        // 替换成实际UI更新逻辑
        UI.GameData.Character.CurrentReadiness = value;
        UI.GameData.Character.UpdateCurrentReadiness();
    }
    
  3. 优化异步调用,避免不必要的线程切换
    原Main.cs中await Task.Run(() => GameData.GetCharacterWindowInformationAsync());可以简化,因为GetCharacterWindowInformationAsync本身就是异步方法,不需要再包一层Task.Run,直接调用即可:

    // 修改Main.cs中的RunAsync方法
    public static async Task RunAsync(MainUI form_mainUI)
    {
        while (true)
        {                
            if (UABA.Status)
            {
                await GameData.GetCharacterWindowInformationAsync(form_mainUI);
            }
            // 可以添加短暂延迟,避免循环占用过多CPU
            await Task.Delay(100);
        }
    }
    

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.19 04:25:54