我正在使用VSTO,我想通过COM Interop为Excel模型(获取和设置rages)操作的任务设置进度条。在执行任何在Excel模型上运行的任务时,强烈建议仅从主线程执行此操作(有很多帖子可以讨论这个问题)。
我的问题是我希望有一个进度条(存在于辅助线程上),我希望能够在进度条加载时启动我的任务(在主线程上)。是否有某种方法可以将函数排入队列以从辅助线程执行主线程?如果没有,还有其他方法可以设置吗?
我的来源如下:
abstract class BaseProgressTask
{
private ProgressForm _form;
public volatile bool CancelPending;
private void ShowProgressForm()
{
_form = new ProgressForm(this) { StartPosition = FormStartPosition.CenterScreen };
_form.ShowDialog();
}
public BaseProgressTask()
{
ThreadStart startDelegate = ShowProgressForm;
Thread thread = new Thread(startDelegate) { Priority = ThreadPriority.Highest };
thread.SetApartmentState(ApartmentState.STA);
thread.Start();
}
public abstract void Run();
protected void ReportProgress(int percent)
{
_form.BeginInvoke(new Action(() => _form.SetProgress(percent)));
}
protected void CloseForm()
{
_form.BeginInvoke(new Action(() => _form.Close()));
}
}
public partial class ProgressForm : Form
{
private BaseProgressTask _task;
public ProgressForm(BaseProgressTask task)
{
InitializeComponent();
_task = task;
}
private void btnCancel_Click(object sender, EventArgs e)
{
_task.CancelPending = true;
lblStatus.Text = "Cancelling...";
}
public void SetProgress(int percent)
{
myProgressBar.Value = percent;
}
private void ProgressForm_Load(object sender, EventArgs e)
{
//Any way to do this?
ExecuteOnMainThread(_task.Run);
}
}
答案 0 :(得分:1)
您可以考虑使用BackgroundWorker组件。它在单独的线程上执行操作,并允许使用事件处理程序以更方便的方式报告进度。有关详细信息,请参阅How to: Use a Background Worker和Walkthrough: Multithreading with the BackgroundWorker Component (C# and Visual Basic)。
Windows API中的SendMessage函数可用于在主线程上运行操作。
如果您的主线程是表单,您可以使用以下简短代码处理它:
if (InvokeRequired)
{
this.Invoke(new Action(() => MyFunction()));
return;
}
或.NET 2.0
this.Invoke((MethodInvoker) delegate {MyFunction();});