如何将例程拆分为线程? [复制]
Posted
技术标签:
【中文标题】如何将例程拆分为线程? [复制]【英文标题】:How do I split a routine into threads? [duplicate] 【发布时间】:2012-03-15 09:57:28 【问题描述】:可能重复:Timing issue - DGV refreshes before process amends the data
我有以下代码
private void btRunReport_Click(object sender, EventArgs e)
Process p = new Process();
p.StartInfo.FileName = @"\\fileserve\department$\ReportScheduler_v3.exe";
p.StartInfo.Arguments = "12";
p.Start();
p.WaitForExit();
InitializeGridView();
p 将更新数据库表 X。 InitializeGridView 更新反映表 X 的 DGV。
问题是如果 p 需要 10 分钟来运行,那么 winForm 在它到达 InitializeGridView() 之前就被冻结了。我需要帮助的是如何让表单在一个单独的线程中启动进程,该线程在幕后工作并运行 InitializeGridView()?
【问题讨论】:
您不能在这样的线程中启动进程,即从前到后,并且触发线程以启动进程将毫无意义。如果您没有 p.WairForExit 您的代码将继续到 InitializeGridView();马上。 简而言之,阅读 C# 4.0 中的Threading in C# - 您尝试做的事情主要是相当容易的。 编辑:错过了您尝试运行 exe 的事实,无论哪种方式,它都是一篇好文章 我认为实现这一点并促进安全取消的唯一方法是使用单独的 AppDomain... 恕我直言,不是重复,而是后续问题。 @till - 同意 - 前一个线程已经结束,这个问题值得单独讨论。虽然我想我可能在上一篇文章的 cmets 中问过这个问题(我会删除它) 【参考方案1】:如果您需要在进程完成后运行 InitialilzeGridView() 方法:
-
将
Dispatcher.CurrentDispatcher
设为_currentDispatcher。
在一个单独的线程中启动进程,并在其中使用WaitForExit()
。
让线程通过_currentDispatcher.BeginInvoke
调用您的InitializeGridview()
方法。
这里有一些代码可以帮助您:
注意:您需要通过项目的“添加引用”对话框添加对 WindowsBase 的引用。
using System;
using System.Diagnostics;
using System.Threading;
using System.Windows.Forms;
using System.Windows.Threading;
private readonly Dispatcher _currentDispatcher = Dispatcher.CurrentDispatcher;
private delegate void ReportingSchedulerFinishedDelegate();
private void btRunReport_Click(object sender, EventArgs e)
btRunReport.Enabled = false;
btRunReport.Text = "Processing..";
var thread = new Thread(RunReportScheduler);
thread.Start();
private void InitializeGridView()
// Whatever you need to do here
private void RunReportScheduler()
Process p = new Process();
p.StartInfo.FileName = @"\\fileserve\department$\ReportScheduler_v3.exe";
p.StartInfo.Arguments = "12";
p.Start();
p.WaitForExit();
_currentDispatcher.BeginInvoke(new ReportingSchedulerFinishedDelegate(ReportingSchedulerFinished), DispatcherPriority.Normal);
private void ReportingSchedulerFinished()
InitializeGridView();
btRunReport.Enabled = true;
btRunReport.Text = "Start";
【讨论】:
直到 - 您的解决方案似乎完美运行 - 我只需要研究它以了解它现在是如何工作的! 这很简单:在自己的线程中运行长时间运行的 RunReportSchedule。后台线程的问题是您可能无法直接访问由主 GUI 线程处理的元素。 _currentDispatcher 将保存来自您的 GUI 线程的调度程序的引用,并且您可以在完成数据准备后通过委托传递指令以运行 ReportSchedulerFinished。以上是关于如何将例程拆分为线程? [复制]的主要内容,如果未能解决你的问题,请参考以下文章
29多线程(线程池定时器)将一个文件复制多次拆分文件并合并多线程复制文件