我遇到的问题是OpenFileDialog.ShowDialog()方法(用于从用户获取保存目录)阻止来自第一个完成的下载线程的主线程回调.这反过来允许其他下载线程完成(不是问题),但随后也开始执行他们的回调到主线程,此时他们都点击OpenFileDialog.ShowDialog(),否则他们不会做我的第二批线程将在第一次转换时运行,因此可以将它们添加到批处理线程管理器中.
我正在使用dispatcher.Currentdispatcher.BeginInvoke(myCallbackDelegate,dispatcherPriority.normal,myParameter),以便在项目工作完成时回调主线程.我在下面创建了一个简化示例来演示问题代码.
public partial class TestForm : Form { private readonly dispatcher dispatcher = dispatcher.Currentdispatcher; //An instance of my own BatchBackgroundWorkerThread<T> class; this class parrarlelizes tasks and can report their individual and overall progress,completion and cancellation. private readonly BatchBackgroundWorkerThread<int> conversionBatchBackgroundWorker = new BatchBackgroundWorkerThread<int>(); public TestForm() { InitializeComponent(); for (int threadindex = 0; threadindex < 4; threadindex++) { new Thread(DoSomeBackgroundWork).Start(threadindex); Thread.Sleep(10); } } private void DoSomeBackgroundWork(object threadindex) { Thread.Sleep(1000); dispatcher.BeginInvoke(new ParameterizedThreadStart(WorkCompletedCallback),threadindex); } private void WorkCompletedCallback(object threadindex) { //Waits for CanQueueNewItems to be in a valid readable state. conversionBatchBackgroundWorker.WaitForPendingRun(); //CanQueueNewItems is true when the batch background worker's batch thread has been launched and its internal CountdownEvent and cancellationState have been initialized. if (conversionBatchBackgroundWorker.IsBusy && conversionBatchBackgroundWorker.CanQueueNewItems) //Queues the item in the BatchBackgroundWorker for parrarelization with any other items. //NOTE: This code is not currently hit unless the user makes a dialog selection before another callback can reach the above if statement. conversionBatchBackgroundWorker.Additem(threadindex); else { FolderbrowserDialog.ShowDialog(); conversionBatchBackgroundWorker.RunWorkerAsync(new int[] { (int)threadindex },FolderbrowserDialog.Selectedpath); } } }
我已经尝试将dispatcherPriority更改为dispatcherPriority.SystemIdle – 这使得所有待处理的ShowDialog对话框在必须单击“确定”或“取消”之前显示,但除此之外结果仍然相同.
有没有办法可以阻止ShowDialog允许执行主线程的其他挂起回调?
更新:
我修改了上面的代码,以更仔细地反映我的实际应用程序中发生的事情.所有回调操作都需要排入我创建的BatchBackgroundWorker类中,以便执行相关的转换.这就是为什么我不能简单地设置变量之前调用ShowDialog()说它被调用,因为剩下的回调然后会尝试将自己排入当前尚未启动的BatchBackgroundWorker(此时BatchBackgroundWorker线程没有运行用户对对话框的响应正在等待启动.
解决方法
wasDialogShown = true; OpenFileDialog.ShowDialog();
您还应该使用wasDialogShown锁定代码部分:
private readonly object dialogLock = new Object(); private void WorkCompletedCallback(object threadindex) { bool wasShown; lock(dialogLock) { wasShown = wasDialogShown; wasDialogShown = true; } if (wasShown) { MessageBox.Show("Success!"); } else { OpenFileDialog.ShowDialog(); } }
Lock Statement会在您读取之后但在将其设置为true之前阻止另一个线程读取wasDialogShown.
更新(响应您的更新)
解决方案可能是有两个状态变量:dialogLaunched和conversionWorkerLaunched.第一个返回任务启动对话框.在启动对话框之后但在启动转换工作程序之前完成此任务和任务将添加到队列中.对话框关闭后,将启动转换并将所有排队的任务添加到其中.启动转换后返回的任务会立即添加到工作程序中.
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 [email protected] 举报,一经查实,本站将立刻删除。