[英]Exception handling with tasks using libraries (dll)
I have a task which gets data using a data access library hooked up to a WCF service. 我有一个任务,该任务使用连接到WCF服务的数据访问库获取数据。 layed out like so: 布局如下:
Data Access dll: 数据访问dll:
using (Service.ServiceClient client = new Service.ServiceClient(EndpointAddress))
{
try
{
//Make my service call
client.close()
//return list
}
catch (FaultException fe)
{
client.Abort();
throw fe;
}
catch (CommunicationException ce)
{
client.Abort();
throw ce;
}
catch (TimeoutException te)
{
client.Abort();
throw te;
}
}
Main Program: 主程序:
Task<List<Stuff>> loadOp = new Task<List<Stuff>>(() => dataAccessDllMethod());
loadOp.Start();
try
{
loadOp.ContinueWith((Sender) =>
{
Sender.Result
}
catch (Exception ex)
{
//Notify User
throw;
}
now my code keeps breaking in the lambda expression of the loadOp meaning the user never gets notified, but from what I've read this is the correct way of error handling in tasks. 现在,我的代码不断破坏loadOp的lambda表达式,这意味着用户永远不会收到通知,但是从我读到的内容来看,这是任务中错误处理的正确方法。 is this the correct way of doing this or is there a better way? 这是这样做的正确方法还是有更好的方法?
When you start a Task
, in your case a Task<List<Stuff>>
, you immediately get back the Task with a promise of it to finish sometime in the future, and your method continues execution , meaning it will finish the try
block and exit. 当启动一个Task
时(如果是Task<List<Stuff>>
,您会立即带着承诺在将来某个时间完成的任务取回Task,并且您的方法会继续执行 ,这意味着它将完成try
块并出口。 It doesn't block or wait for the Task
to complete. 它不会阻止或等待Task
完成。 There are a couple of things you may do: 您可以做几件事:
Task.Result
property which waits for the Result of the Task
while blocking the thread. 访问Task.Result
属性,该属性在阻止线程的同时等待Task
的结果。 Task.Wait()
, which waits for the Task
to complete also blocking the thread. 调用Task.Wait()
,它等待Task
完成也阻塞了线程。 await
on the Task
, which doesn't block like the previous two, but yields control back to the caller, until the Task
finishes execution . await
Task
,它不会像前两个Task
一样阻塞,而是将控制权交还给调用者,直到Task
完成执行为止 。 In order to be able to do that, the compiler generates a state machine which takes care of everything for us. 为了做到这一点,编译器生成了一个状态机,该状态机为我们处理了所有事情。 throw
the exception to propogate it up the call stack it won't work unless someone accesses Result
or Exception
properties of the continued Task
请注意,如果您尝试throw
异常,除非有人访问传播完成它调用堆栈它不会工作Result
或Exception
持续的性质Task
What i would do instead of creating different continuations for success or failure, would simply await
: 我会做什么,而不是创建成功或失败不同的延续,只会await
:
Task<List<Stuff>> loadOp = Task.Run<List<Stuff>>(() => dataAccessDllMethod());
try
{
Task<List<Stuff>> loadOp = await Task.Run<List<Stuff>>(() => dataAccessDllMethod());
// do stuff with the result
}
catch (Exception ex)
{
//Notify User
throw;
}
One last thing, the recommanded approach is to always use Task.Run
or Task.Factory.Startnew
when creating tasks so you accidentally forget to Start
them and return a Cold Task
which never executes (using new Task
) 最后一件事,建议的方法是在创建任务时始终使用Task.Run
或Task.Factory.Startnew
,因此您不小心忘记Start
它们并返回一个永远不会执行的Cold Task
(使用new Task
)
try below code I guess you don't require try catch you can directly write the code as shown below.. :- 尝试下面的代码我想您不需要try catch,您可以直接编写如下所示的代码..:-
loadOp.ContinueWith((Sender) =>
{
////this will be called on successful completion
Sender.Result
}, TaskContinuationOptions.OnlyOnRanToCompletion);
loadOp.ContinueWith((Sender) =>
{
////Notify user
////This will be called when error occures
Sender.Result
}, TaskContinuationOptions.OnlyOnFaulted);
The OnlyOnFaulted member of the TaskContinuationOptions enumeration indicates that the continuation should only be executed if the antecedent task threw an exception. TaskContinuationOptions枚举的OnlyOnFaulted成员指示仅当先前任务引发异常时才应继续执行。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.