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

如何在控制台应用Main方法中调用public static async void方法?

嘿,你的这段代码存在几个关键问题,先不说能不能实现连接TFS的目标,首先编译大概率就通不过,咱们来一步步拆解和修正:

先说说你当前实现的核心问题

  • 首先,GetProjects是静态方法,你却实例化了GetProjectClass对象去调用,完全没必要,直接用GetProjectClass.GetProjects()调用就行,但这不是最严重的问题。
  • 核心坑点:你用了async void作为方法返回值!async void是专门给UI事件处理器设计的,普通异步方法绝对不能用这个返回类型——因为它不会返回Task,你根本没法用.Wait()去等待它完成,看你Main里写的t.GetProjects().Wait(),编译器会直接报错,因为GetProjects()是void类型,没有.Wait()方法。
  • 另外,你在GetProjects里调用client.GetAsync(...).Result,这是同步阻塞调用异步方法,很容易导致死锁,完全违背了异步编程的初衷,应该改成await来等待异步操作完成。

正确的修改方案

第一步:修正GetProjects方法

把async void改成async Task,并且把.Result替换成await,让方法返回可等待的Task:

using System;
using System.Net.Http;
using System.Net.Http.Headers;
using System.Threading.Tasks;

namespace ConsoleApplication2
{
    public class GetProjectClass
    {
        // 将async void改为async Task,让方法返回可等待的任务
        public static async Task GetProjects()
        {
            try
            {
                var personalaccesstoken = "PAT_FROM_WEBSITE";
                using (HttpClient client = new HttpClient())
                {
                    client.DefaultRequestHeaders.Accept.Add(
                        new MediaTypeWithQualityHeaderValue("application/json"));
                    client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Basic", 
                        Convert.ToBase64String(System.Text.ASCIIEncoding.ASCII.GetBytes(string.Format("{0}:{1}", "", personalaccesstoken))));
                    
                    // 用await替代.Result,避免死锁
                    using (HttpResponseMessage response = await client.GetAsync(
                        "https://{account}.visualstudio.com/DefaultCollection/_apis/projects"))
                    {
                        response.EnsureSuccessStatusCode();
                        string responseBody = await response.Content.ReadAsStringAsync();
                        Console.WriteLine(responseBody);
                    }
                }
            }
            catch (Exception ex)
            {
                Console.WriteLine(ex.ToString());
            }
        }
    }
}

第二步:修正Program的Main方法

如果你的项目使用C# 7.1及以上版本,可以直接把Main改成异步方法,用await等待任务完成,这是最推荐的方式:

using System;
using System.Threading.Tasks;

namespace ConsoleApplication2
{
    class Program
    {
        // 改为async Task Main,支持异步等待
        static async Task Main(string[] args)
        {
            // 静态方法直接调用,无需实例化对象
            await GetProjectClass.GetProjects();
            Console.WriteLine("finished");
            Console.ReadKey();
        }
    }
}

如果你的C#版本低于7.1,没法用异步Main,可以用GetAwaiter().GetResult()来安全等待任务完成(比.Wait()更不容易触发死锁):

using System;

namespace ConsoleApplication2
{
    class Program
    {
        static void Main(string[] args)
        {
            GetProjectClass.GetProjects().GetAwaiter().GetResult();
            Console.WriteLine("finished");
            Console.ReadKey();
        }
    }
}

最后再划几个异步编程的重点

  • 普通异步方法永远不要用async void,优先用async Task(无返回值)或async Task<T>(有返回值);
  • 异步方法内部尽量全程用await,不要混用.Result或.Wait()这类同步阻塞调用,避免死锁;
  • 控制台程序优先使用异步Main(C#7.1+),写法更简洁安全。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.15 04:21:47