<SYSTEM_TASK:>
Solve the following problem using Python, implementing the functions described below, one line at a time
<END_TASK>
<USER_TASK:>
Description:
 async def upload_fileobj(self, Fileobj: BinaryIO, Bucket: str, Key: str, ExtraArgs: Optional[Dict[str, Any]] = None, Callback: Optional[Callable[[int], None]] = None, Config: Optional[S3TransferConfig] = None):
 """Upload a file-like object to S3. The file-like object must be in binary mode. This is a managed transfer which will perform a multipart upload in multiple threads if necessary. Usage:: import boto3 s3 = boto3.client('s3') with open('filename', 'rb') as data: s3.upload_fileobj(data, 'mybucket', 'mykey') :type Fileobj: a file-like object :param Fileobj: A file-like object to upload. At a minimum, it must implement the `read` method, and must return bytes. :type Bucket: str :param Bucket: The name of the bucket to upload to. :type Key: str :param Key: The name of the key to upload to. :type ExtraArgs: dict :param ExtraArgs: Extra arguments that may be passed to the client operation. :type Callback: method :param Callback: A method which takes a number of bytes transferred to be periodically called during the upload. :type Config: boto3.s3.transfer.TransferConfig :param Config: The transfer configuration to be used when performing the upload. """

    if not ExtraArgs:
        ExtraArgs = {}

    # I was debating setting up a queue etc...
    # If its too slow I'll then be bothered
    multipart_chunksize = 8388608 if Config is None else Config.multipart_chunksize
    io_chunksize = 262144 if Config is None else Config.io_chunksize
    # max_concurrency = 10 if Config is None else Config.max_concurrency
    # max_io_queue = 100 if config is None else Config.max_io_queue

    # Start multipart upload

    resp = await self.create_multipart_upload(Bucket=Bucket, Key=Key, **ExtraArgs)
    upload_id = resp['UploadId']

    part = 0
    parts = []
    running = True
    sent_bytes = 0

    try:
        while running:
            part += 1
            multipart_payload = b''
            while len(multipart_payload) < multipart_chunksize:
                if asyncio.iscoroutinefunction(Fileobj.read):  # handles if we pass in aiofiles obj
                    data = await Fileobj.read(io_chunksize)
                else:
                    data = Fileobj.read(io_chunksize)

                if data == b'':  # End of file
                    running = False
                    break
                multipart_payload += data

            # Submit part to S3
            resp = await self.upload_part(
                Body=multipart_payload,
                Bucket=Bucket,
                Key=Key,
                PartNumber=part,
                UploadId=upload_id
            )
            parts.append({'ETag': resp['ETag'], 'PartNumber': part})
            sent_bytes += len(multipart_payload)
            try:
                Callback(sent_bytes)  # Attempt to call the callback, if it fails, ignore, if no callback, ignore
            except:  # noqa: E722
                pass

        # By now the uploads must have been done
        await self.complete_multipart_upload(
            Bucket=Bucket,
            Key=Key,
            UploadId=upload_id,
            MultipartUpload={'Parts': parts}
        )
    except:  # noqa: E722
        # Cancel multipart upload
        await self.abort_multipart_upload(
            Bucket=Bucket,
            Key=Key,
            UploadId=upload_id
        )

        raise