2

这是我的问题:-

我正在构建一个客户端-服务器应用程序,在该应用程序中我将请求发布到服务器以为我生成 2 个 XML(服务器从数据库中获取信息并根据获取的信息生成 XML)。现在,一旦服务器创建了这 2 个 XML,服务器将这 2 个文件流回客户端,以便客户端可以将它们保存在他们的机器上。

(发布+从流中阅读)是一项工作。如果没有第二个操作,即从流中读取,作业是不完整的。

我在 eclipse 中创建了一个作业,它将请求发布到服务器并获取流文件并将它们保存在客户端计算机上。将请求发布到服务器是一个异步调用(它会立即返回)。一旦调用被发布并立即返回,我开始在网络管道上轮询任何数据服务器已发送(在本例中是 XML 的数据)并将其写入文件。

正如您在此处看到的,从流中读取 XML 并将它们写入文件是整个主作业的一部分,但它本身仍然是一个单独的作业(应该在单独的线程中运行)。如果用户取消主作业,从网络流中读取也应该被取消。

所以,基本上我的要求是完成这一切的可取消工作。从流中读取应该是单独的线程/作业,但应该在主作业内。如果用户取消了主作业,这个内部作业(从作业中读取)也应该被取消。

你们能建议一种干净的方法吗?

-Ankit

4

2 回答 2

3

您可以创建一个主作业,并在该主作业中创建一个子作业。如果主作业被取消,您可以将取消委托给子作业。

我用两个按钮创建了一个简单的视图。一个用于启动作业,另一个用于取消。

package rcpexperiments;

import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.Status;
import org.eclipse.core.runtime.jobs.IJobChangeEvent;
import org.eclipse.core.runtime.jobs.Job;
import org.eclipse.core.runtime.jobs.JobChangeAdapter;
import org.eclipse.swt.SWT;
import org.eclipse.swt.events.SelectionAdapter;
import org.eclipse.swt.events.SelectionEvent;
import org.eclipse.swt.widgets.Button;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.ui.part.ViewPart;

public class View extends ViewPart
{
  private Job mainJob;

  @Override
  public void createPartControl(final Composite parent)
  {
    final Button button = new Button(parent, SWT.PUSH);
    button.setText("Start Job");
    button.addSelectionListener(new SelectionAdapter()
    {

      @Override
      public void widgetSelected(final SelectionEvent e)
      {
        mainJob = new Job("Main Job")
        {

          private boolean canceled = false;

          @Override
          protected void canceling()
          {
            System.out.println("Cancel requested.");
            canceled = true;
          }

          @Override
          protected IStatus run(final IProgressMonitor monitor)
          {
            final Job subJob = createSubJob();
            subJob.schedule();
            canceled = false;
            while (!canceled)
            {
              try
              {
                Thread.sleep(100);
              }
              catch (final InterruptedException e)
              {
              }
            }
            subJob.cancel();
            System.out.println("Main Job is canceled.");
            return Status.CANCEL_STATUS;
          }

          private Job createSubJob()
          {
            return new Job("Sub Job")
            {
              boolean subJobCancel = false;

              @Override
              protected void canceling()
              {
                subJobCancel = true;
              }

              @Override
              protected IStatus run(final IProgressMonitor monitor)
              {
                System.out.println("Sub Job started.");
                while (!subJobCancel)
                {
                  try
                  {
                    Thread.sleep(100);
                  }
                  catch (final InterruptedException e)
                  {
                  }
                }
                System.out.println("Sub Job canceled");
                return Status.CANCEL_STATUS;
              }

            };
          }

        };
        mainJob.addJobChangeListener(new JobChangeAdapter()
        {
          @Override
          public void done(final IJobChangeEvent event)
          {
            System.out.println("Job finished by " + event.getResult());
          }
        });
        mainJob.schedule();

        System.out.println("Main Job started.");
      };

    });
    final Button cancel = new Button(parent, SWT.PUSH);
    cancel.setText("Cancel");
    cancel.addSelectionListener(new SelectionAdapter()
    {

      @Override
      public void widgetSelected(final SelectionEvent e)
      {
        mainJob.cancel();
      }

    });
  }

  /** {@inheritDoc} */
  @Override
  public void setFocus()
  {
  }

}

我希望那是你想要的。

于 2012-08-01T08:53:43.900 回答
1

在我看来,按照 Micheal K. 建议的方式定义子作业有点麻烦。所以我查看了 Eclipse 文档,发现Job类定义了一个名为 createProgressGroup 的静态方法,可以按如下方式使用(相同的文档),它做的事情大致相同:

Job parseJob, compileJob;
IProgressMonitor pm = Job.getJobManager().createProgressGroup();
try {
   pm.beginTask("Building", 10);
   parseJob.setProgressGroup(pm, 5);
   parseJob.schedule();
   compileJob.setProgressGroup(pm, 5);
   compileJob.schedule();
   parseJob.join();
   compileJob.join();
} finally {
   pm.done();
}

请注意,不推荐使用 IJobManager.getJobManager。

于 2012-12-21T15:36:29.400 回答