Search code examples
azure-batch

Getting 'This operation is forbidden on unbound objects' when trying to monitor an Azure Batch task


I want to execute a simple task in Azure Batch, to wait until it completes and to get the result:

using (var client = _CreateBatchClient())
{
    var monitor = client.Utilities.CreateTaskStateMonitor();

    var task = new CloudTask(Guid.NewGuid().ToString(), "echo hello world");
    await client.JobOperations.AddTaskAsync("Test", task);
    await monitor.WhenAll(new List<CloudTask> { task }, TaskState.Completed, _timeout);

    var result = task.ExecutionInformation.Result;
}

And the WhenAsync line throws System.InvalidOperationException: 'This operation is forbidden on unbound objects.'

The message is quite obscure whereas I am not far from the tutorial. What is wrong?


Solution

  • It is not obvious from this code yet actually Azure Batch does not know here how to identify the task. The job contains tasks but a task has no reference to a job it runs on. And the task Id does not globally identify the task as well, it only needs to be unique within a job.

    This is probably the meaning of "unbound objects" here. The monitor just does not understand what to watch. Actually, if the WhenAsync line is commented, the next one throws a similar InvalidOperationException: 'The property ExecutionInformation cannot be read while the object is in the Unbound state.'

    So the right way is to reference the task via the job:

    using (var client = _CreateBatchClient())
    {
        var monitor = client.Utilities.CreateTaskStateMonitor();
    
        var id = Guid.NewGuid().ToString();
        var taskToAdd = new CloudTask(id, "echo hello world");
        await client.JobOperations.AddTaskAsync("Test", taskToAdd);
    
        var taskToTrack = await client.JobOperations.GetTaskAsync("Test", id);
        await monitor.WhenAll(new List<CloudTask> { taskToTrack }, TaskState.Completed, _timeout);
    }
    

    Compare:

    task to add task to track

    And to get the result information, one needs to "find" the task in the job again, or it will be null.