2

これが私の質問です:-

私はクライアントサーバーアプリケーションを構築しているところです。サーバーにリクエストを送信して、2つのXMLを生成します(サーバーはDBから情報をフェッチし、このフェッチされた情報に基づいてXMLを生成します)。これで、サーバーがこれら2つのXMLを作成すると、サーバーはこれら2つのファイルをクライアントにストリーミングして戻し、クライアントがそれらを自分のマシンに保存できるようにします。

(投稿+ストリームからの読み取り)は1つの仕事です。2番目の操作、つまりストリームからの読み取りがないと、ジョブは不完全です。

Eclipseでジョブを作成しました。このジョブは、サーバーにリクエストを送信し、ストリーミングされたファイルを取得してクライアントマシンに保存します。サーバーへのリクエストの投稿は非同期呼び出しです(すぐに返されます)。呼び出しが投稿されてすぐに返されると、ネットワークパイプで、サーバーが送信したデータ(この場合はXMLのデータ)のポーリングを開始し、ファイルに書き込みます。

ここでわかるように、ストリームからXMLを読み取り、ファイルに書き込むことは、全体的なメインジョブの一部ですが、それ自体は別のジョブです(別のスレッドで実行する必要があります)。ユーザーがメインジョブをキャンセルした場合、ネットワークストリームからの読み取りもキャンセルする必要があります。

ですから、基本的に私の要件は、このすべてを実行するキャンセル可能な仕事です。ストリームからの読み取りは、個別のスレッド/ジョブである必要がありますが、メインジョブ内にある必要があります。ユーザーがメインジョブをキャンセルした場合、この内部ジョブ(ジョブからの読み取り)もキャンセルされます。

皆さんはこれを行うためのクリーンなアプローチを提案できますか?

-アンキット

4

2 に答える 2

3

メインジョブを作成し、そのメインジョブ内にサブジョブを作成できます。メインジョブがキャンセルされた場合は、キャンセルをサブジョブに委任できます。

2つのボタンでシンプルなビューを作成しました。1つはジョブの開始用で、もう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()
  {
  }

}

それがあなたが望んでいたことだといいのですが。

于 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 に答える