Perform the following steps to create and run a program that can add a job to the Distributed Computing (Job Processor) SDK. In this tutorial the Job Processor is used to convert images from any supported format to PDF using one of the LEADTOOLS Imaging SDKs. Use this tutorial in conjunction with the (Creating a Job Processor Worker) tutorial, which demonstrates how to create a Job Processor worker assembly capable of actually converting the file. For the sake of simplicity, assume the client and worker are on the same machine.
Start Visual Studio
Choose File->New->Project from the menu
In the New Project dialog box, choose either "Visual C# Projects" or "VB Projects" in the Projects Type List, and choose "Windows Application" in Visual Studio 2005 or "Windows Forms Application" in Visual Studio 2008 from the Templates List
Type the project name as "JobProcessorAddJobsTutorial" in the Project Name field, and then click OK. If desired, type a new location for your project or select a directory using the Browse button, and then click OK.
Drag and drop the following controls onto Form1, using the names and text values below:
| Control Type | Name | Text |
| Button | _btnAddJob | Add Job |
| Textbox | _txtJobID | |
| Button | _btnGetJobStatus | Get Job Status |
| Button | _btnOpenConvertedFile | Open Converted File |
Switch to Form1 code view (Right-click Form1 in the solution explorer then select View Code) and add the following lines at the beginning of the file after any Imports or using section if there are any:
Imports JobProcessorAddJobsTutorial.JobServiceImports System.IOImports System.Xml.SerializationImports System.Diagnostics
using JobProcessorAddJobsTutorial.JobService;using System.IO;using System.Xml.Serialization;using System.Diagnostics;
Add the following code to the Form1 constructor (in VB, you can copy/paste the whole Sub New code from here):
Sub New()' This call is required by the Windows Form Designer.InitializeComponent()' Add any initialization after the InitializeComponent() call.' Set the LEADTOOLS runtime license' Replace with your own keyDim MY_LICENSE_FILE As String = "d:\temp\TestLic.lic"Dim MY_DEVELOPER_KEY As String = "xyz123abc"RasterSupport.SetLicense(MY_LICENSE_FILE, MY_DEVELOPER_KEY)End Sub
public Form1(){InitializeComponent();// Set the LEADTOOLS license// Replace with your own keystring MY_LICENSE_FILE = "d:\\temp\\TestLic.lic";string MY_DEVELOPER_KEY = "xyz123abc";RasterSupport.SetLicense(MY_LICENSE_FILE, MY_DEVELOPER_KEY);}
Add the following structure and method to the class (see comments for explanation).
'This method will be used to store the conversion settings (how the file should be converted).'We will serialize it at the Job Processor client, and the worker assembly will deserialize it to obtain the settings.Friend Structure JobMetadataPublic SourceFile As StringPublic TargetFile As StringPublic Sub New(ByVal _sourceFile As String, ByVal _targetFile As String)SourceFile = _sourceFileTargetFile = _targetFileEnd SubEnd Structure'Serialize the job metadata to an xml string so it can be stored in the Job Processor database,'and deserialize it later by the worker assembly when the job is processed.Private Function SerializeToString(ByVal jobMetadata As JobMetadata) As StringUsing sw As StringWriter = New StringWriter()Dim xmlSerializer As XmlSerializer = New XmlSerializer(GetType(JobMetadata))xmlSerializer.Serialize(sw, jobMetadata)Return sw.ToString()End UsingEnd Function'Deserialize the JobMetadataPublic Function DeserializeFromString(ByVal serializedString As String) As JobMetadataDim serializedBytes As Byte() = Encoding.Unicode.GetBytes(serializedString)Using ms As MemoryStream = New MemoryStream(serializedBytes)Dim xmlSerializer As XmlSerializer = New XmlSerializer(GetType(JobMetadata))Return CType(xmlSerializer.Deserialize(ms), JobMetadata)End UsingEnd FunctionPrivate Function GetJobInformation() As GetJobInformationResponseUsing jobServiceClient As JobServiceClient = New JobServiceClient()Dim getJobInformationRequest As GetJobInformationRequest = New GetJobInformationRequest()getJobInformationRequest.ID = _txtJobID.TextReturn jobServiceClient.GetJobInformation(getJobInformationRequest)End UsingEnd Function
//This method will be used to store the conversion settings (how the file should be converted).//We will serialize it at the Job Processor client, and the worker assembly will deserialize it to obtain the settings.struct JobMetadata{public string SourceFile;public string TargetFile;public JobMetadata(string _sourceFile, string _targetFile){SourceFile = _sourceFile;TargetFile = _targetFile;}}//Serialize the job metadata to an xml string so it can be stored in the Job Processor database,//and deserialize it later by the worker assembly when the job is processed.string SerializeToString(JobMetadata jobMetadata){using (StringWriter sw = new StringWriter()){XmlSerializer xmlSerializer = new XmlSerializer(typeof(JobMetadata));xmlSerializer.Serialize(sw, jobMetadata);return sw.ToString();}}//Deserialize the JobMetadatapublic JobMetadata DeserializeFromString(string serializedString){byte[] serializedBytes = Encoding.Unicode.GetBytes(serializedString);using (MemoryStream ms = new MemoryStream(serializedBytes)){XmlSerializer xmlSerializer = new XmlSerializer(typeof(JobMetadata));return (JobMetadata)xmlSerializer.Deserialize(ms);}}private GetJobInformationResponse GetJobInformation(){using (JobServiceClient jobServiceClient = new JobServiceClient()){GetJobInformationRequest getJobInformationRequest = new GetJobInformationRequest();getJobInformationRequest.ID = _txtJobID.Text;return jobServiceClient.GetJobInformation(getJobInformationRequest);}}
Add the following code for the _btnAddJob (Add Job) control’s Click handler:
Private Sub _btnAddJob_Click(ByVal sender As Object, ByVal e As EventArgs)TryUsing ofd As OpenFileDialog = New OpenFileDialog()If ofd.ShowDialog() = DialogResult.OK ThenUsing jobServiceClient As JobServiceClient = New JobServiceClient()Dim addJobRequest As AddJobRequest = New AddJobRequest()addJobRequest.UserToken = "User1"'Create the metadata to store the conversion settings.Dim convertedFilePath As string = Path.Combine(Path.GetDirectoryName(ofd.FileName), Path.GetFileNameWithoutExtension(ofd.FileName) & ".pdf")Dim jobMetadata As JobMetadata = New JobMetadata(ofd.FileName, convertedFilePath)addJobRequest.JobMetadata = SerializeToString(jobMetadata)addJobRequest.JobType = "ConvertToPDF"Dim addJobResponse As AddJobResponse = jobServiceClient.AddJob(addJobRequest)If (Not String.IsNullOrEmpty(addJobResponse.ID)) Then_txtJobID.Text = addJobResponse.IDElseMessageBox.Show("The job was not added")End IfEnd UsingEnd IfEnd UsingCatch ex As ExceptionMessageBox.Show(ex.Message)End TryEnd Sub
private void _btnAddJob_Click(object sender, EventArgs e){try{using (OpenFileDialog ofd = new OpenFileDialog()){if (ofd.ShowDialog() == DialogResult.OK){using (JobServiceClient jobServiceClient = new JobServiceClient()){AddJobRequest addJobRequest = new AddJobRequest();addJobRequest.UserToken = "User1";//Create the metadata to store the conversion settings.string convertedFilePath = Path.Combine(Path.GetDirectoryName(ofd.FileName), Path.GetFileNameWithoutExtension(ofd.FileName) + ".pdf");JobMetadata jobMetadata = new JobMetadata(ofd.FileName, convertedFilePath);addJobRequest.JobMetadata = SerializeToString(jobMetadata);addJobRequest.JobType = "ConvertToPDF";AddJobResponse addJobResponse = jobServiceClient.AddJob(addJobRequest);if (!String.IsNullOrEmpty(addJobResponse.ID))_txtJobID.Text = addJobResponse.ID;elseMessageBox.Show("The job was not added");}}}}catch (Exception ex){MessageBox.Show(ex.Message);}}
Add the following code for the _btnGetJobStatus (Get Job Status) control’s Click handler:
Private Sub _btnGetJobStatus_Click(ByVal sender As Object, ByVal e As EventArgs)TryIf String.IsNullOrEmpty(_txtJobID.Text) ThenMessageBox.Show("No job ID has been entered")ReturnEnd IfUsing jobServiceClient As JobServiceClient = New JobServiceClient()Dim getJobInformationResponse As GetJobInformationResponse = GetJobInformation()If Not getJobInformationResponse.JobInformation Is Nothing AndAlso (Not String.IsNullOrEmpty(getJobInformationResponse.JobInformation.ID)) Then'Show the job informationDim jobInfo As String = String.EmptyjobInfo = String.Format("Job ID: {0}{1}", getJobInformationResponse.JobInformation.ID, Environment.NewLine)jobInfo = jobInfo & String.Format("Add Time: {0}{1}", getJobInformationResponse.JobInformation.AddedTime, Environment.NewLine)jobInfo = jobInfo & String.Format("Status: {0}{1}", getJobInformationResponse.JobInformation.Status, Environment.NewLine)jobInfo = jobInfo & String.Format("Attempts: {0}{1}", getJobInformationResponse.JobInformation.Attempts, Environment.NewLine)If (Not String.IsNullOrEmpty(getJobInformationResponse.JobInformation.JobType)) ThenjobInfo = jobInfo & String.Format("Job Type: {0}{1}", getJobInformationResponse.JobInformation.JobType, Environment.NewLine)End IfIf Not getJobInformationResponse.JobInformation.LastStartedTime Is Nothing ThenjobInfo = jobInfo & String.Format("Last Started Time: {0}{1}", getJobInformationResponse.JobInformation.LastStartedTime, Environment.NewLine)End IfIf Not getJobInformationResponse.JobInformation.LastUpdatedTime Is Nothing ThenjobInfo = jobInfo & String.Format("Last Updated Time: {0}{1}", getJobInformationResponse.JobInformation.LastUpdatedTime, Environment.NewLine)End IfIf getJobInformationResponse.JobInformation.Status = JobStatus.Started ThenjobInfo = jobInfo & String.Format("Progress: {0}{1}", getJobInformationResponse.JobInformation.Percentage, Environment.NewLine)End IfIf (Not String.IsNullOrEmpty(getJobInformationResponse.JobInformation.Worker)) ThenjobInfo = jobInfo & String.Format("Worker: {0}{1}", getJobInformationResponse.JobInformation.Worker, Environment.NewLine)End IfIf getJobInformationResponse.JobInformation.Status = JobStatus.Completed ThenjobInfo = jobInfo & String.Format("Completed Time: {0}{1}", getJobInformationResponse.JobInformation.CompletedTime, Environment.NewLine)End IfIf getJobInformationResponse.JobInformation.Status = JobStatus.Failed ThenjobInfo = jobInfo & String.Format("Failed Time: {0}{1}", getJobInformationResponse.JobInformation.FailedTime, Environment.NewLine)jobInfo = jobInfo & String.Format("Error ID: {0}{1}", getJobInformationResponse.JobInformation.FailureInformation.FailedErrorID, Environment.NewLine)jobInfo = jobInfo & String.Format("Error Message: {0}{1}", getJobInformationResponse.JobInformation.FailureInformation.FailedMessage, Environment.NewLine)End IfMessageBox.Show(jobInfo, "Job Info")ElseMessageBox.Show("The specified job ID was not found.")ReturnEnd IfEnd UsingCatch ex As ExceptionMessageBox.Show(ex.Message)End TryEnd Sub
private void _btnGetJobStatus_Click(object sender, EventArgs e){try{if (String.IsNullOrEmpty(_txtJobID.Text)){MessageBox.Show("No job ID has been entered");return;}using (JobServiceClient jobServiceClient = new JobServiceClient()){GetJobInformationResponse getJobInformationResponse = GetJobInformation();if (getJobInformationResponse.JobInformation != null && !String.IsNullOrEmpty(getJobInformationResponse.JobInformation.ID)){//Show the job informationstring jobInfo = String.Empty;jobInfo = String.Format("Job ID: {0}{1}", getJobInformationResponse.JobInformation.ID, Environment.NewLine);jobInfo = jobInfo + String.Format("Add Time: {0}{1}", getJobInformationResponse.JobInformation.AddedTime, Environment.NewLine);jobInfo = jobInfo + String.Format("Status: {0}{1}", getJobInformationResponse.JobInformation.Status, Environment.NewLine);jobInfo = jobInfo + String.Format("Attempts: {0}{1}", getJobInformationResponse.JobInformation.Attempts, Environment.NewLine);if (!String.IsNullOrEmpty(getJobInformationResponse.JobInformation.JobType))jobInfo = jobInfo + String.Format("Job Type: {0}{1}", getJobInformationResponse.JobInformation.JobType, Environment.NewLine);if (getJobInformationResponse.JobInformation.LastStartedTime != null)jobInfo = jobInfo + String.Format("Last Started Time: {0}{1}", getJobInformationResponse.JobInformation.LastStartedTime, Environment.NewLine); ;if (getJobInformationResponse.JobInformation.LastUpdatedTime != null)jobInfo = jobInfo + String.Format("Last Updated Time: {0}{1}", getJobInformationResponse.JobInformation.LastUpdatedTime, Environment.NewLine);if (getJobInformationResponse.JobInformation.Status == JobStatus.Started)jobInfo = jobInfo + String.Format("Progress: {0}{1}", getJobInformationResponse.JobInformation.Percentage, Environment.NewLine);if (!String.IsNullOrEmpty(getJobInformationResponse.JobInformation.Worker))jobInfo = jobInfo + String.Format("Worker: {0}{1}", getJobInformationResponse.JobInformation.Worker, Environment.NewLine);if (getJobInformationResponse.JobInformation.Status == JobStatus.Completed)jobInfo = jobInfo + String.Format("Completed Time: {0}{1}", getJobInformationResponse.JobInformation.CompletedTime, Environment.NewLine);if (getJobInformationResponse.JobInformation.Status == JobStatus.Failed){jobInfo = jobInfo + String.Format("Failed Time: {0}{1}", getJobInformationResponse.JobInformation.FailedTime, Environment.NewLine);jobInfo = jobInfo + String.Format("Error ID: {0}{1}", getJobInformationResponse.JobInformation.FailureInformation.FailedErrorID, Environment.NewLine);jobInfo = jobInfo + String.Format("Error Message: {0}{1}", getJobInformationResponse.JobInformation.FailureInformation.FailedMessage, Environment.NewLine);}MessageBox.Show(jobInfo, "Job Info");}else{MessageBox.Show("The specified job ID was not found.");return;}}}catch (Exception ex){MessageBox.Show(ex.Message);}}
Add the following code for the _btnOpenConvertedFile (Open Converted File) control’s Click handler:
Private Sub _btnOpenConvertedFile_Click(ByVal sender As Object, ByVal e As EventArgs)TryIf String.IsNullOrEmpty(_txtJobID.Text) ThenMessageBox.Show("No job ID has been entered")ReturnEnd IfDim getJobInformationResponse As GetJobInformationResponse = GetJobInformation()If Not getJobInformationResponse.JobInformation Is Nothing AndAlso (Not String.IsNullOrEmpty(getJobInformationResponse.JobInformation.ID)) ThenDim jobMetadata As JobMetadata = DeserializeFromString(getJobInformationResponse.JobInformation.Metadata.JobMetadata)If (Not String.IsNullOrEmpty(jobMetadata.TargetFile)) AndAlso File.Exists(jobMetadata.TargetFile) ThenUsing process As Process = New Process()'Open converted fileprocess.StartInfo.FileName = jobMetadata.TargetFileprocess.Start()End UsingEnd IfEnd IfCatch ex As ExceptionMessageBox.Show(ex.Message)End TryEnd Sub
private void _btnOpenConvertedFile_Click(object sender, EventArgs e){try{if (String.IsNullOrEmpty(_txtJobID.Text)){MessageBox.Show("No job ID has been entered");return;}GetJobInformationResponse getJobInformationResponse = GetJobInformation();if (getJobInformationResponse.JobInformation != null && !String.IsNullOrEmpty(getJobInformationResponse.JobInformation.ID)){JobMetadata jobMetadata = DeserializeFromString(getJobInformationResponse.JobInformation.Metadata.JobMetadata);if (!String.IsNullOrEmpty(jobMetadata.TargetFile) && File.Exists(jobMetadata.TargetFile)){using (Process process = new Process()){//Open converted fileprocess.StartInfo.FileName = jobMetadata.TargetFile;process.Start();}}}}catch (Exception ex){MessageBox.Show(ex.Message);}}
Build, and run the program to test it. Click the 'Add Job' button to browse to any supported image file and add it to the Job Processor database. If added successfully, the newly added job's ID will be added to the textbox. Click the 'Get Job Status' to obtain the status of your job. After the status of your job is 'Completed', click the 'Open Converted File' to open the converted file.
Note: Keep in mind the job will not actually be processed until you configure a worker to process jobs of this type (ConvertToPDF). See the Creating Job Processor Worker Assemblies tutorial for more information.
LEADTOOLS Job Processor Settings
Understanding The LEADTOOLS Job Processor Database
Creating Job Processor Worker Assemblies
Deploying LEADTOOLS Distributed Computing (JobProcessor) Applications