gpt4 book ai didi

c# - 线程和 ArcGIS

转载 作者:太空宇宙 更新时间:2023-11-03 20:46:32 28 4
gpt4 key购买 nike

我刚刚偶然发现了 Backgroundworker 对象,它似乎是我正在寻找的工具,可以让我的 GUI 在执行计算时做出响应。我正在为 ArcGIS 编写 IO 插件。

我正在 ArcGIS 之外进行一些数据处理,使用后台工作器可以正常工作。但是当我将数据插入 ArcGIS 时,后台工作人员似乎将持续时间增加了 9 倍左右。将处理代码放在 DoWork 方法之外,可将性能提高 9 倍。

我已经在网上的几个地方读到过这方面的内容,但我没有多线程编程方面的经验,而且像 STA 和 MTA 这样的术语对我来说毫无意义。 link text我也尝试过使用简单的线程实现,但结果相似。

有谁知道我可以做些什么来使用 ArcGIS 处理和维护响应式 GUI?

编辑:我已经包含了我与后台工作人员互动的示例。如果我将位于 StartImporting 方法中的代码放在 cmdStart_Click 方法中,它的执行速度会快得多。

private void StartImporting(object sender, DoWorkEventArgs e)
{
DateTime BeginTime = DateTime.Now;
// Create a new report object.
SKLoggingObject loggingObject = new SKLoggingObject("log.txt");
loggingObject.Start("Testing.");

SKImport skImporter = new SKImport(loggingObject);
try
{
// Read from a text box - no writing.
skImporter.Open(txtInputFile.Text);
}
catch
{
}
SKGeometryCollection convertedCollection = null;

// Create a converter object.
GEN_SK2ArcGIS converter = new GEN_SK2ArcGIS(loggingObject);

// Convert the data.
convertedCollection = converter.Convert(skImporter.GetGeometry());

// Create a new exporter.
ArcGISExport arcgisExporter = new ArcGISExport(loggingObject);

// Open the file.
// Read from a text box - no writing.
arcgisExporter.Open(txtOutputFile.Text);

// Insert the geometry collection.
try
{
arcgisExporter.Insert(convertedCollection);
}
catch
{
}
TimeSpan totalTime = DateTime.Now - BeginTime;
lblStatus.Text = "Done...";

}

private void ChangeProgress(object sender, ProgressChangedEventArgs e)
{
// If any message was passed, display it.
if (e.UserState != null && !((string)e.UserState).Equals(""))
{
lblStatus.Text = (string)e.UserState;
}
// Update the progress bar.
pgStatus.Value = e.ProgressPercentage;
}

private void ImportDone(object sender, RunWorkerCompletedEventArgs e)
{
// If the process was cancelled, note this.
if (e.Cancelled)
{
pgStatus.Value = 0;
lblStatus.Text = "Operation was aborted by user...";
}
else
{
}

}

private void cmdStart_Click(object sender, EventArgs e)
{
// Begin importing the sk file to the geometry collection.

// Initialise worker.
bgWorker = new BackgroundWorker();
bgWorker.RunWorkerCompleted += new RunWorkerCompletedEventHandler(ImportDone);
bgWorker.ProgressChanged += new ProgressChangedEventHandler(ChangeProgress);
bgWorker.DoWork += new DoWorkEventHandler(StartImporting);
bgWorker.WorkerReportsProgress = true;
bgWorker.WorkerSupportsCancellation = true;

// Start worker.
bgWorker.RunWorkerAsync();

}

private void cmdCancel_Click(object sender, EventArgs e)
{
bgWorker.CancelAsync();
}

亲切的问候,卡斯珀

最佳答案

在 ArcGIS 中使用 COM 对象时,应该使用 STA 线程是正确的。不过,您仍然可以获得 BackgroundWorker 的便利,它始终是系统线程池中的 MTA 线程。

private static void OnBackgroundWorkerDoWork(object sender, DoWorkEventArgs e)
{
BackgroundWorker worker = (BackgroundWorker)sender;
ToolToStart tool = e.Argument as ToolToStart;

if (tool != null)
{
tool.BackgroundWorker = worker;

// The background worker thread is an MTA thread,
// and should not operate on ArcObjects/COM types.
// Instead we create an STA thread to run the tool in.
// When the the tool finishes the infomation from the STA thread
// is transferred to the background worker's event arguments.
Thread toolThread = new Thread(STAThreadStart);
toolThread.SetApartmentState(ApartmentState.STA);
toolThread.Start(tool);

toolThread.Join();
e.Cancel = m_ToolCanceled;
e.Result = m_ToolResult;
}
}

STA 线程现在可以使用 BackgroundWorker 的方法,例如报告进度、检查取消和报告结果。

protected virtual void StatusUpdateNotify(ProgressState progressState)
{
if (BackgroundWorker.CancellationPending)
{
throw new OperationCanceledException();
}

BackgroundWorker.ReportProgress(progressState.Progress, progressState);
}

除了在操作 ArcGIS 对象时仅使用 STA 线程外,您不应在两个线程之间共享对象。从您的代码看来,您似乎是从后台工作人员访问 GUI 的:lblStatus.Text = "Done...";,这可以在例如RunWorkerComplete 的委托(delegate)。

关于c# - 线程和 ArcGIS,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/658301/

28 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com