Helio Castroneves denied Takuma Sato his first IndyCar victory in a close-fought battle around the Edmonton airport circuit.