【问题标题】:How to manage a separate thread/job within a eclipse job?如何在 Eclipse 作业中管理单独的线程/作业?
【发布时间】:2017-03-16 22:27:11
【问题描述】:

这是我的问题:-

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

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

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

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

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

你们能提出一个干净的方法吗?

-Ankit

【问题讨论】:

    标签: eclipse-rcp


    【解决方案1】:

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

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

    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()
      {
      }
    
    }
    

    我希望这是你想要的。

    【讨论】:

    • 非常感谢迈克尔。它非常接近我的需要。你的回答无疑给了我一个方向。我将根据我的要求修改代码。再次感谢
    【解决方案2】:

    在我看来,按照 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 已弃用。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2010-10-08
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-08-08
      • 1970-01-01
      相关资源
      最近更新 更多