Я выполнил имя службы ExamClient
, которые имеют две операции один является Ping
, которые возвращают основной string
который означает сервис доступен и один FindStudy
который поиск в БД может занять долго продолжаться.Лучший способ справиться с исключением в нескольких задач вызвать операцию WCF
В другой стороны, я несколько оконечных ExamClient
я палочка запустить FindStudy
за конечную точку по задаче так в Dispatcher
у меня есть что-то вроде этого:
public FindStudies_DTO_OUT FindStudies(FindStudies_DTO_IN findStudies_DTO_IN)
{
List<Study_C> ret = new List<Study_C>();
List<Task> tasks = new List<Task>();
foreach (var sp in Cluster)
{
string serviceAddress = sp.GetLibraryAddress(ServiceLibrary_C.PCM) + "/Exam.svc";
var task = Task.Run(() =>
{
ExamClient examClient = new ExamClient(serviceAddress.GetBinding(), new EndpointAddress(serviceAddress), Token);
var ping = Task.Run(() =>
{
examClient.Ping();
});
if (!ping.Wait(examClient.Endpoint.Binding.OpenTimeout))
{
Logging.Log(LoggingMode.Warning, "Timeout on FindStudies for:{0}, address:{1}", sp.Name, serviceAddress);
return new List<Study_C>(); // if return null then need to manage it on ret.AddRange(t.Result);
}
return (examClient.FindStudies(findStudies_DTO_IN).Studies.Select(x =>
{
x.StudyInstanceUID = string.Format("{0}|{1}", sp.Name, x.StudyInstanceUID);
x.InstitutionName = sp.Name;
return x;
}));
});
task.ContinueWith(t =>
{
lock (ret)
{
ret.AddRange(t.Result);
}
}, TaskContinuationOptions.OnlyOnRanToCompletion);
task.ContinueWith(t =>
{
Logging.Log(LoggingMode.Error, "FindStudies failed for :{0}, address:{1}, EXP:{2}", sp.Name, serviceAddress, t.Exception.ToString());
}, TaskContinuationOptions.OnlyOnFaulted);
tasks.Add(task);
}
try
{
Task.WaitAll(tasks.ToArray());
}
catch (AggregateException aggEx)
{
foreach (Exception exp in aggEx.InnerExceptions)
{
Logging.Log(LoggingMode.Error, "Error while FindStudies EXP:{0}", exp.ToString());
}
}
return new FindStudies_DTO_OUT(ret.Sort(findStudies_DTO_IN.SortColumnName, findStudies_DTO_IN.SortOrderBy));
}
Сначала я должен запустить Ping
в конечной точке чтобы узнать подключение установлено после этого FindStudy
.
Если есть три конца пинты в Cluster
, то шесть задач должны выполняться в параллельном режиме, 3 для Ping
и 3 для FindStudy
.
Я думаю, что что-то не так с моим кодом, чтобы справиться с исключением ... Итак, каков наилучший способ реализации этого сценария?
благодарит заранее.
Вы не должны использовать 'Wait()' внутри своих задач, чтобы получить доступ к логике тайм-аута .... см. Ответ [здесь] (http://stackoverflow.com/questions/4238345/asynchronously-wait-for -taskt-to-complete-with-timeout) –
Посмотрите также на комментарии относительно материала маркера отмены. Это действительно важно! –
Я думаю, что я должен ждать, потому что время открытия составляет 3 секунды, если доступна конечная точка «Ping» получить ответ в течение 3 секунд. – Aria