我们正在使用msgraph API连接30多个邮箱,但服务在运行2-3天后挂起。主要的罪魁祸首是GetAsync()方法用户。下面是ParallelThreadOne的代码。类似的代码也适用于其他线程。
public static async Task MainAsync()
{
Task t1 = ParallelThreadOne.MainAsync();
Task t2 = ParallelThreadSecond.MainAsync();
Task t3 = ParallelThreadThird.MainAsync();
await Task.WhenAll(t1, t2, t3);
}
public static async Task MainAsync()
{
try
{
EmailMaster objEmailMaster = new EmailMaster();
List<MailBoxConfiguration> lstMailBoxConfiguration = objEmailMaster.GetMailBoxInformation(1, logger);
if (lstMailBoxConfiguration != null)
{
if (lstMailBoxConfiguration.Count != 0)
{
Global.client = await Global.GetAuthenticatedClient();
if (client != null)
{
for (int j = 0; j < lstMailBoxConfiguration.Count; j++)
{
var users = await Global.client
.Users
.Request()
.Filter("startswith(Mail,'" + lstMailBoxConfiguration[j].EmailId + "')")
.GetAsync();
if (users.Count > 0)
{
var msgs = await Global.client
.Users[users[0].Id]
.MailFolders["Inbox"].Messages
.Request().Top(500)
.GetAsync();
if (msgs.Count > 0)
{
foreach (var item in msgs)
{
//business logic goes here
}
}
else
{
logger.Info("msg.Count is zero");
}
}
else
{
logger.Info("users.Count is zero");
}
}
}
else
{
logger.Info("client is null");
}
}
else
{
logger.Info("lstMailBoxConfiguration.Count is zero from the database");
}
}
else
{
logger.Info("lstMailBoxConfiguration is null from the database");
}
logger.Info("MainAsync(1) : End of MainAsync(1)");
}
catch (Exception ex)
{
logger.Error("MainAsync(1) : Exception : " + ex.Message);
}
}
public static class Global
{
public static GraphServiceClient graphClient = null;
public static string clientId = ConfigurationManager.AppSettings["AzureClientId"];
public static string password = ConfigurationManager.AppSettings["password"];
private static HttpClient client = new HttpClient();
public static string tenantId = ConfigurationManager.AppSettings["tenantId"];
public static string grantType = "client_credentials";
public static string getTokenUrl = $"https_://login.microsoftonline.com/{tenantId}/oauth2/v2.0/token";
public const string myScopes = "https_://graph.microsoft.com/.default";
public static string postBody = $"client_id={clientId}&scope={myScopes}&client_secret={password}&grant_type={grantType}";
private static string userToken;
public static Task<GraphServiceClient> GetAuthenticatedClient(NLog.Logger logger)
{
if (graphClient == null)
{
try
{
graphClient = new GraphServiceClient(
"https_://graph.microsoft.com/v1.0",
new DelegateAuthenticationProvider(
async (requestMessage) =>
{
HttpRequestMessage httpRequestMessage = new HttpRequestMessage(HttpMethod.Post, getTokenUrl);
httpRequestMessage.Content = new StringContent(postBody, Encoding.UTF8, "application/x-www-form-urlencoded");
HttpResponseMessage httpResponseMessage = await client.SendAsync(httpRequestMessage);
string responseBody = await httpResponseMessage.Content.ReadAsStringAsync();
userToken = JObject.Parse(responseBody).GetValue("access_token").ToString();
requestMessage.Headers.Authorization = new AuthenticationHeaderValue("bearer", userToken);
}));
return Task.FromResult(graphClient);
}
catch (OutOfMemoryException ex)
{
logger.Error("GetAuthenticatedClient_Out of memory Exception: " + ex.Message);
}
catch (Exception ex)
{
logger.Error("Could not create a graph client: " + ex.Message);
}
}
return Task.FromResult(graphClient);
}
我们正在使用DLL版本microsoft.graph(3.20.0) µsoft.graph.core(1.22.0)和应用程序是窗口服务(c#)和框架是4.6.1
创建一个MS图形客户端,如下面的链接,可以在应用程序的生命周期内作为单个客户端实例使用。
这是连接保持打开状态的强烈信号。它解释了服务在几天后挂起的行为
https://learn.microsoft.com/en-us/graph/sdks/create-client?tabs=CS
参考SO线程:windows服务在c#微软图形api getAsync()调用的用户进入挂起状态