Eisenrich
Eisenrich

Reputation: 7

TPL return value and exception

I have develop a library that connects and operate with devices. For example:

public bool Connect(string ip)
{
    try
    {
        // try connect to device
    }
    catch (Exception ex)
    {
        // trow custom exception
    }
}

This is ok, but now I have decided to include in my library TPL.

The problem I'm facing is with the logic of how to return values. Instead of passing an IP, you will pass a list of IP's. Imagine you want to connect to 10 devices and 5 are ok and the other 5 are faulted I image a code like:

public Dictionary<Device, bool> Connect(List<Device> device)
{
    try
    {
        // TPL try connect to device
    }
    catch (AggregatedException ex)
    {
        // trow custom exception
    }
}

If someone calls this method they would only receive the exeption, in this case it can be easy but for example, if I have another method like Dictionary<Device, List<Logs>> GetLogs(List<Device> device) I would have 5 devices with data and 5 devices faulted.

What is the best way to return a result for the correct connections and the errors for the faulted ones? A connection can fail for several reasons.

UPDATE

I have tried this:

    public Dictionary<int, Task<string>> GetData3(int value)
    {
        Dictionary<int, Task<string>> dic = new Dictionary<int, Task<string>>();
        Task<string>[] tasks = new Task<string>[value];
        for (int i = 0; i < value; i++)
        {
            tasks[i] = Task.Factory.StartNew<string>((stateObject) =>
            {
                var a = (int)stateObject;
                return a + " Test";
            }, value);
            dic.Add(i, tasks[i]);
        }
        Task.WaitAll(tasks);

        return dic;
    }

And in the WS Client:

        Service1Client sc = new Service1Client();
        var a = sc.GetData3(5);

If i break in return dic i can see the results:

Id = 1, Status = RanToCompletion, Method = "{null}", Result = "5 Test"

But in var a I only see:

Id = 1, Status = WaitingForActivation, Method = "{null}", Result = "{Not yet computed}"

Upvotes: 0

Views: 551

Answers (1)

Jon Skeet
Jon Skeet

Reputation: 1502286

You could return a Dictionary<Device, Task<Whatever>> (where Whatever would be the result for each device). You could return that immediately, having started connecting to each device. Then the task would represent (on a per-device basis) whether the connection had completed, failed, or was still on-going.

Aside from anything else, using tasks for asynchronous results is pretty much the idiomatic way of using TPL... and made easier in C# 5 with async/await.

If the caller wants to wait for all of the tasks to complete, and aggregate any exceptions, they can do so.

Upvotes: 1

Related Questions