code: function patchMacroTask(obj, funcName, metaCreator) {
      var setNative = null;
      function scheduleTask(task) {
          var data = task.data;
          data.args[data.cbIdx] = function () {
              task.invoke.apply(this, arguments);
          };
          setNative.apply(data.target, data.args);
          return task;
      }
      setNative = patchMethod(obj, funcName, function (delegate) { return function (self, args) {
          var meta = metaCreator(self, args);
          if (meta.cbIdx >= 0 && typeof args[meta.cbIdx] === 'function') {
              return scheduleMacroTaskWithCurrentZone(meta.name, args[meta.cbIdx], meta, scheduleTask);
          }
          else {
              // cause an error by calling it directly.
              return delegate.apply(self, args);
          }
      }; });
  }
docs: TODO: @JiaLiPassion, support cancel task later if necessary