简体   繁体   English

使用库(dll)处理任务的异常

[英]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: 您可以做几件事:

  1. Access Task.Result property which waits for the Result of the Task while blocking the thread. 访问Task.Result属性,该属性在阻止线程的同时等待Task的结果。
  2. Invoke Task.Wait() , which waits for the Task to complete also blocking the thread. 调用Task.Wait() ,它等待Task完成也阻塞了线程。
  3. 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. 为了做到这一点,编译器生成了一个状态机,该状态机为我们处理了所有事情。
  4. As Neel suggested, add a continuation which take care of the previous task faulting. 正如Neel所建议的那样,添加一个继续项来处理先前的任务错误。 Note that if you try to 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异常,除非有人访问传播完成它调用堆栈它不会工作ResultException持续的性质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.RunTask.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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM