Actually, after further research, I believe the return value from Pool.apply_async needs to be an object defined at the top-level of any module.  In the end, I decided to write my own Result class that stores the information available through the arcpy.Result methods and lets you retrieve them with an identical interface.  It is picklable if all the inputs and outputs are picklable.  For my case, I'm mostly using datasets represented as path strings.
class Result(object):
    def __init__(self, status, inputs, outputs, messages):
        """Initializes the result.
        ARGUMENT            DESCRIPTION
        --------            -----------
        status              The job status.
        inputs              The inputs to the job.
        outputs             The outputs of the job.
        messages            The messages of the job represented as a list of
                            tuples whose values are (severity, message).
        
        STATUS              DESCRIPTION
        ------              -----------
        0                   New
        1                   Submitted
        2                   Waiting
        3                   Executing
        4                   Succeeded
        5                   Failed
        6                   Timed Out
        7                   Cancelling
        8                   Cancelled
        9                   Deleting
        10                  Deleted
        
        SEVERITY            DESCRIPTION
        --------            -----------
        0                   Informational Message
        1                   Warning Message
        2                   Error Message
        """
        self._status = status
        """The job status.
        STATUS              DESCRIPTION
        ------              -----------
        0                   New
        1                   Submitted
        2                   Waiting
        3                   Executing
        4                   Succeeded
        5                   Failed
        6                   Timed Out
        7                   Cancelling
        8                   Cancelled
        9                   Deleting
        10                  Deleted
        """
        self._inputs = inputs
        """The inputs to the job."""
        self._outputs = outputs
        """The outputs of the job."""
        self._messages = messages
        """The messages of the job represented as a list of tuples whose values
        are (severity, message).
        
        SEVERITY            DESCRIPTION
        --------            -----------
        0                   Informational Message
        1                   Warning Message
        2                   Error Message
        """
    @classmethod
    def from_arcpy_result(cls, result):
        """Creates a Result from an arcpy.Result instance.
        ARGUMENT            DESCRIPTION
        --------            -----------
        result              An instance of arcpy.Result.
        """
        assert isinstance(result, arcpy.Result), (
            "Result %r is not an instance of arcpy.Result." % result)
        status = result.status
        inputs = [result.getInput(i) for i in range(result.inputCount)]
        outputs = [result.getOutput(i) for i in range(result.outputCount)]
        messages = []
        for i in range(result.messageCount):
            messages.append((result.getSeverity(i), result.getMessage(i)))
        return cls(status, inputs, outputs, messages)
    @property
    def inputCount(self):
        """The number of inputs of the job."""
        return len(self._inputs)
    @property
    def maxSeverity(self):
        """The maximum severity of the messages.
        
        SEVERITY            DESCRIPTION
        --------            -----------
        0                   Informational Message
        1                   Warning Message
        2                   Error Message
        """
        return max([severity for severity, message in self._messages])
    @property
    def messageCount(self):
        """The number of messages."""
        return len(self._messages)
    @property
    def outputCount(self):
        """The number of outputs."""
        return len(self._outputs)
    @property
    def resultID(self):
        """The job ID if the tool is a geoprocessing service, else ""."""
        return self._resultID
    @property
    def status(self):
        """The job status.
        STATUS              DESCRIPTION
        ------              -----------
        0                   New
        1                   Submitted
        2                   Waiting
        3                   Executing
        4                   Succeeded
        5                   Failed
        6                   Timed Out
        7                   Cancelling
        8                   Cancelled
        9                   Deleting
        10                  Deleted
        """
        return self._status
    def cancel(self):
        """Cancels the job."""
        pass
    def getInput(self, index):
        """Returns the input at the given index, either as a record set or a
        string.
        ARGUMENT            DESCRIPTION
        --------            -----------
        index               Index of the input to return.
        """
        return self._inputs[index]
    def getMapImageURL(self, *args, **kwargs):
        """Returns a map service image for a given output, if one exists."""
        raise NotImplementedError
    def getMessage(self, index):
        """Returns the message at the given index.
        ARGUMENT            DESCRIPTION
        --------            -----------
        index               Index of the message to return.
        """
        return self._messages[index]
    def getMessages(self, severity=0):
        """Returns messages of the given severity or greater.
        SEVERITY            DESCRIPTION
        --------            -----------
        0                   Informational Message
        1                   Warning Message
        2                   Error Message
        """
        messages = []
        for s, m in self._messages:
            if s >= severity:
                messages.append(m)
        return "\n".join(messages)
    def getOutput(self, index):
        """Returns the output at the given index, either as a record set or a
        string.
        ARGUMENT            DESCRIPTION
        --------            -----------
        index               Index of the output to return.
        """
        return self._outputs[index]
    def getSeverity(self, index):
        """"Returns the severity of the message at the given index.
        SEVERITY            DESCRIPTION
        --------            -----------
        0                   Informational Message
        1                   Warning Message
        2                   Error Message
        """
        return self._messages[index][0]