2017-05-24 123 views
0

我想實現Facebook登錄並獲取C#項目中的數據。 我想要做的是該用戶按他的名字和密碼,然後他按登錄按鈕並登錄然後它返回他的數據。 當我按下按鈕程序凍結。使用C#訪問Facebook API等待並永久卡住

這是我的項目實施

Account.cs

public class Account 
{ 
    public string Id { get; set; } 
    public string Name { get; set; } 
    public string Email { get; set; } 
    public string Birthday { get; set; } 
} 

Facebook.client

public interface IFacebookClient 
{ 
    Task<T> GetAsync<T>(string accessToken, string endpoint, string args = null); 
    Task PostAsync(string accessToken, string endpoint, object data, string args = null); 
} 

public class FacebookClient : IFacebookClient 
{ 
    private readonly HttpClient _httpClient; 

    public FacebookClient() 
    { 
     _httpClient = new HttpClient 
     { 
      BaseAddress = new Uri("https://graph.facebook.com/v2.8/") 
     }; 
     _httpClient.DefaultRequestHeaders 
      .Accept 
      .Add(new MediaTypeWithQualityHeaderValue("application/json")); 
    } 

    public async Task<T> GetAsync<T>(string accessToken, string endpoint, string args = null) 
    { 
     var response = await _httpClient.GetAsync($"{endpoint}?access_token={accessToken}&{args}"); 
     if (!response.IsSuccessStatusCode) 
      return default(T); 

     var result = await response.Content.ReadAsStringAsync(); 

     return JsonConvert.DeserializeObject<T>(result); 
    } 

    public async Task PostAsync(string accessToken, string endpoint, object data, string args = null) 
    { 
     var payload = GetPayload(data); 
     await _httpClient.PostAsync($"{endpoint}?access_token={accessToken}&{args}", payload); 
    } 

    private static StringContent GetPayload(object data) 
    { 
     var json = JsonConvert.SerializeObject(data); 

     return new StringContent(json, Encoding.UTF8, "application/json"); 
    } 
} 

FacebookService.cs

public interface IFacebookService 
{ 
    Task<Account> GetAccountAsync(string accessToken); 
    Task PostOnWallAsync(string accessToken, string message); 
} 

public class FacebookService : IFacebookService 
{ 
    private readonly IFacebookClient _facebookClient; 

    public FacebookService(IFacebookClient facebookClient) 
    { 
     _facebookClient = facebookClient; 
    } 

    public async Task<Account> GetAccountAsync(string accessToken) 
    { 
     var result = await _facebookClient.GetAsync<dynamic>(
      accessToken, "me", "fields=id,name,birthday,email"); 

     if (result == null) 
     { 
      return new Account(); 
     } 

     var account = new Account 
     { 
      Id = result.id, 
      Email = result.email, 
      Name = result.name, 
      Birthday = result.Birthday 
     }; 

     return account; 
    } 
    public async Task PostOnWallAsync(string accessToken, string message) 
     => await _facebookClient.PostAsync(accessToken, "me/feed", new {message}); 
} 

FacebookSettings.cs

var facebookClient = new FacebookClient(); 
     var facebookService = new FacebookService(facebookClient); 
     var getAccountTask = facebookService.GetAccountAsync(FacebookSettings.AccessToken); 
     Task.WaitAll(getAccountTask); 
     var account = getAccountTask.Result; 
     Console.WriteLine($"{account.Id} {account.Name}"); 

登錄表單按鈕

private void btn_facebook_Click(object sender, EventArgs e) 
    { 
     var facebookClient = new FacebookClient(); 
     var facebookService = new FacebookService(facebookClient); 
     var getAccountTask = facebookService.GetAccountAsync(FacebookSettings.AccessToken); 
     Task.WaitAll(getAccountTask); 
     var account = getAccountTask.Result; 
     //Console.WriteLine($"{account.Id} {account.Name}"); 
    } 

它停留在此行中的await

public async Task<Account> GetAccountAsync(string accessToken) 
    { 
     var result = await _facebookClient.GetAsync<dynamic>(accessToken, "me", "fields=id,name,birthday,email"); 

     if (result == null) 
     { 
      return new Account(); 
     } 

     var account = new Account 
     { 
      Id = result.id, 
      Email = result.email, 
      Name = result.name, 
      Birthday = result.Birthday 
     }; 

     return account; 
    } 

在這一行

  var result = await _facebookClient.GetAsync<dynamic>(accessToken, "me", "fields=id,name,birthday,email"); 

回答

1

這是你的問題:

Task.WaitAll(getAccountTask); 

Don't block on async code。改爲使用await

private async void btn_facebook_Click(object sender, EventArgs e) 
{ 
    var facebookClient = new FacebookClient(); 
    var facebookService = new FacebookService(facebookClient); 
    var account = await facebookService.GetAccountAsync(FacebookSettings.AccessToken); 
}