因为arcengine的一些算法模块实现是com模块不支持backgroundwork,想要进程展示就需要自己创建线程,参考大佬的代码进行了修改和实现。
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
pgStatus.Maximum = 100;
}
private volatile bool AbortOperation;
Func<bool> AbortOperationDelegate;
FinishProcessDelegate finishDelegate;
UpdateGUIDelegate updateGUIDelegate;
private delegate void UpdateGUIDelegate(int progress, object message);
private delegate void FinishProcessDelegate();
public delegate void ProgressEventHandler(int progress, string msg);
private void ProcessFinished()
{
// Post processing.
MessageBox.Show("执行完毕");
return;
}
private void UpdateGUI(int progress, object message)
{
// If the call has been placed at the local thread, call it on the main thread.
if (this.pgStatus.InvokeRequired)
{
UpdateGUIDelegate guidelegate = new UpdateGUIDelegate(UpdateGUI);
this.Invoke(guidelegate, new object[] { progress, message });
}
else
{
// The call was made on the main thread, update the GUI.
pgStatus.Value = progress;
lblStatus.Text = (string)message;
}
}
private void StartProcess()
{
// Update GUI.
updateGUIDelegate(0, "Beginning process...");
// Create object.
Converter converter = new Converter(AbortOperationDelegate);
// Parse the GUI update method to the converter, so it can update the GUI from within the converter.
converter.Progress += new ProgressEventHandler(UpdateGUI);
// Begin converting.
converter.Execute();
// Tell the main thread, that the process has finished.
FinishProcessDelegate finishDelegate = new FinishProcessDelegate(ProcessFinished);
Invoke(finishDelegate);
// Update GUI.
updateGUIDelegate(100, "Process has finished.");
}
private void button1_Click(object sender, EventArgs e)
{
// Create finish delegate, for determining when the thread is done.
finishDelegate = new FinishProcessDelegate(ProcessFinished);
// A delegate for updating the GUI.
updateGUIDelegate = new UpdateGUIDelegate(UpdateGUI);
// Create a delegate function for abortion.
AbortOperationDelegate = () => AbortOperation;
Thread BackgroundThread = new Thread(new ThreadStart(StartProcess));
// Force single apartment state. Required by ArcGIS.
BackgroundThread.SetApartmentState(ApartmentState.STA);
BackgroundThread.Start();
}
private void button2_Click(object sender, EventArgs e)
{
AbortOperation = true;
}
}
public class Converter
{
private Func<bool> AbortOperation { get; set;}
public Converter(Func<bool> abortOperation)
{
AbortOperation = abortOperation;
}
public void Execute()
{
// Calculations using ArcGIS are done here.
int i = 0;
Type factoryType = Type.GetTypeFromProgID("esriGeometry.SpatialReferenceEnvironment");
System.Object obj = Activator.CreateInstance(factoryType);
ISpatialReferenceFactory pfactory = obj as ISpatialReferenceFactory3;
var selectReference = pfactory.CreateESRISpatialReferenceFromPRJFile(@"F:\proj\GCS_92xiamen.prj");
var spatialReference = pfactory.CreateESRISpatialReferenceFromPRJFile(@"F:\proj\GCS_China_Geodetic_Coordinate_System_2000.prj");
while(i<100) // Insert your own criteria here.
{
// Update GUI, and replace the '...' with the progress.
OnProgressChange(new ProgressEventArgs(i, "Still working..."+i));
//pp = GetGeo(tPntCollection.Point[i].X, tPntCollection.Point[i].Y);
IPoint pt = new PointClass();
pt.PutCoords(39594469.58710, 2713518.80515);
IGeometry geo = pt;
geo.SpatialReference = spatialReference;
geo.Project(selectReference);//目标坐标系
IPoint pp = geo as IPoint;
Thread.Sleep(500);
i++;
// Check for abortion at anytime here...
if (AbortOperation.Invoke())
{
MessageBox.Show("任务终止");
return;
}
}
}
public DesktopWindowsApplication2.Form1.ProgressEventHandler Progress;
public virtual void OnProgressChange(ProgressEventArgs e)
{
var p = Progress;
if (p != null)
{
// Invoke the delegate.
p(e.Progress, e.Message);
}
}
}
public class ProgressEventArgs : EventArgs
{
public int Progress { get; set; }
public string Message { get; set; }
public ProgressEventArgs(int _progress, string _message)
{
Progress = _progress;
Message = _message;
}
}
参考于https://stackoverflow.com/questions/658301/threading-and-arcgis