jeszcze pytanie
jest metoda async/await
inna metoda z niej korzysta, ale ona juz nie bedzie async, więc zeby poczekała na rezultat wrzucam:
void SomeMethod()
{
someService.GetSthAsync().Result;
}
i dlaczego to powyżej czasem nie zadziała:
przypadek jest taki, że robię request do async controllera,
przy debugu wraca z metody, dochodzi do return Ok(result);
ale przeglądarka dalej czeka na rezultat.
O co w tym chodzi?
I drugie pytanie - czy poniższy kod jest właściwy?
Tworzę w nim 2 taski, które uderzają do 2 różnych serwisów (a tamte do 2 róznych serwerów (AD+Exchange) + wykonują niektóre operacje async)
public Result<IList<GroupDto>> GetGroups(string name)
{
var groups = new List<GroupDto>();
var findGroupsTasks = new Task[]
{
new Task(() =>
{
var exchangeGroups = _cloudADService.FindGroups(name);
if(exchangeGroups!=null && exchangeGroups.Any())
groups.AddRange(exchangeGroups);
}),
new Task(() =>
{
var adGroups = _aDGroupsService.GetGroups(name);
if(adGroups.IsSuccess && adGroups.Value.Any())
groups.AddRange(adGroups.Value);
})
};
foreach (var task in findGroupsTasks)
task.Start();
Task.WaitAll(findGroupsTasks);
var result = Result.Ok<IList<GroupDto>>(groups);
return result;
}
I to działa (ale czy to jest dobrze napisane?),
I jsezcze kolejny przykład, z taskami + asynciem
public async Task<IList<GroupDto>> GetGroupsOwnedBy(string email)
{
List<GroupDto> adGroups = null;
List<GroupDto> exchangeGroups = null;
var ownedGroupstasks = new Task[]
{
new Task(() =>
{
try {
var userOwnedAD = _groupRepository.GetGroupsOwnedByUser(email).ToArray();
adGroups = new List<GroupDto>(userOwnedAD.Count());
if(userOwnedAD != null && userOwnedAD.Length >0)
adGroups.AddRange(userOwnedAD);
}
catch (Exception ex) { _logger.Error($"Could not get owned groups from ActiveDirectory, {ex.Message}"); }
}),
new Task(() =>
{
try
{
var groups = _cloudADService.GetUserOwnedGroups(email);
var creationInfos = new List<GroupCreationDto>();
exchangeGroups = new List<GroupDto>(groups.Count());
var groupCreations =_groupCreationRepisotry.GetGroupCreationInfo(groups.Select(x=>x.GroupId).ToArray()).Result;
Parallel.ForEach(groups, (group) =>
{
var info = groupCreations.FirstOrDefault(x=>x.GroupId == group.GroupId);
var groupExists = GroupsHelper.GroupExists(info);
if(groupExists)
{
group.ExpirationDate = info?.ExpirationDate;
exchangeGroups.Add(group);
}
});
}
catch{}
})
};
foreach (var task in ownedGroupstasks)
task.Start();
Task.WaitAll(ownedGroupstasks);
var result = new List<GroupDto>();
if (adGroups != null && adGroups.Any()) result.AddRange(adGroups);
if (exchangeGroups != null && exchangeGroups.Any()) result.AddRange(exchangeGroups);
return result;
}
to powyższe również działa, ale nie działało gdy zamiast
new Task(() =>
{
try
{
var groups = _cloudADService.GetUserOwnedGroups(email);
var creationInfos = new List<GroupCreationDto>();
exchangeGroups = new List<GroupDto>(groups.Count());
var groupCreations =_groupCreationRepisotry.GetGroupCreationInfo(groups.Select(x=>x.GroupId).ToArray()).Result;
zrobiłem w ten sposób:
new Task(async () =>
{
try
{
var groups = _cloudADService.GetUserOwnedGroups(email);
var creationInfos = new List<GroupCreationDto>();
exchangeGroups = new List<GroupDto>(groups.Count());
var groupCreations =await _groupCreationRepisotry.GetGroupCreationInfo(groups.Select(x=>x.GroupId).ToArray());
Czy w ogóle dobrze to obsługuje?
Szczerze mówiąc dopiero od niedawna mam styczność z asyncami na poziomie controllerów i w ogóle asynchronicznością/wielowątkowością, itd