我正在做一个补丁来解决一个有点混乱的应用程序中的进度条问题.进度条上的取消用于Thread.Abort执行繁重工作的线程.我把它改为提出取消标志,我可以在线程的战略位置检查.
大部分时间它工作正常但偶尔取消根本不起作用.我想Application.DoEvents在查看旗帜的状态之前我可以做一个(没有重新进入的风险),但我想要一个更"干净"的选择.
如果有人能够提供信息以了解究竟发生了什么以及这些东西如何在幕后工作,我将不胜感激.我想知道如何处理这个问题而不使用BackgroundWorker(就像你在.net 1.1中那样),但我也想知道BackgroundWorker解决那种问题以及它是如何解决的.
编辑:我正在记录你的建议,明天会尝试一些并报告.我最初使用了挥发性bool,我认为我将其更新为自动属性并忘记了volatile.工作线程可以一次又一次地查找缓存的值吗?我不知道怎么会有死锁.工作人员检查标志,因为我设法通过在运行中放置一个断点来打破那里.我总是使用相同的数据集进行测试,大部分时间它都取消了.测试之间唯一的变化就是我按下取消的那一刻.到目前为止,我只在调试中测试过,从VS开始.
编辑2:事实证明,我的问题与我的旗帜或我添加的任何内容无关.这更像是一个WinForm问题.该程序可以调用a ShowDialog(并且已经阻止了另一个ShowDialog).我无法拖动表单,它不会自动刷新.它上面的取消按钮甚至不起作用.当我暂停一切时,这是调用堆栈.
[Code externe]
Mrnf.Son.Commun.dll!Mrnf.Son.Commun.Messages.BarreProgressionBase.ShowDialog(System.Windows.Forms.IWin32Window fenetre = {Mrnf.Son.Presentation.Windows.UI.Echanges.AssistantForm}) Ligne 274 + 0xb octets C#
Mrnf.Son.Commun.dll!Mrnf.Son.Commun.Controleurs.Utils.AttendreFinTraitement(System.Windows.Forms.Form parent = {Mrnf.Son.Presentation.Windows.UI.Echanges.AssistantForm}, Mrnf.Son.Commun.Messages.BarreProgressionBase progressionBase = {Mrnf.Son.Commun.Messages.BarreProgressionMessage}, System.Threading.Thread thread = {System.Threading.Thread}) Ligne 302 + 0xd octets C#
Mrnf.Son.Affaires.dll!Mrnf.Son.Affaires.Persisteurs.Echanges.LecteurDBFGeneriqueCollection.Importer(System.Windows.Forms.Form parent = {Mrnf.Son.Presentation.Windows.UI.Echanges.AssistantForm}) Ligne 95 + 0x1d octets C#
Mrnf.Son.Affaires.dll!Mrnf.Son.Affaires.Persisteurs.Echanges.PersisteurModeleEchanges.Importer(Mrnf.Son.Affaires.Entites.Echanges.ModeleEchanges unModele = {Mrnf.Son.Presentation.Windows.Controleurs.Echanges.ModeleEchanges.ModeleEchangesGenerique}, System.Windows.Forms.Form formParent = {Mrnf.Son.Presentation.Windows.UI.Echanges.AssistantForm}) Ligne 1880 + 0xd octets C#
Mrnf.Son.Affaires.dll!Mrnf.Son.Affaires.Entites.Echanges.ModeleEchanges.Importer(System.Windows.Forms.Form formParent = {Mrnf.Son.Presentation.Windows.UI.Echanges.AssistantForm}) Ligne 875 + 0x18 octets C#
Mrnf.Son.Presentation.Windows.exe!Mrnf.Son.Presentation.Windows.UI.Echanges.AssistantForm.EffectuerImport(Mrnf.Son.Affaires.Entites.Echanges.IModeleEchanges modele = {Mrnf.Son.Presentation.Windows.Controleurs.Echanges.ModeleEchanges.ModeleEchangesGenerique}) Ligne 1429 + 0xc octets C#
Mrnf.Son.Presentation.Windows.exe!Mrnf.Son.Presentation.Windows.UI.Echanges.AssistantForm._terminerBtn_Click(object sender = {Text = Impossible d'évaluer l'expression, car un frame natif se trouve en haut de la pile des appels.}, System.EventArgs e = {System.EventArgs}) Ligne 1334 + 0x1d octets C#
[Code externe]
Mrnf.Son.Presentation.Windows.exe!Mrnf.Son.Presentation.Windows.UI.Echanges.AssistantForm.WndProc(ref System.Windows.Forms.Message m = {System.Windows.Forms.Message}) Ligne 1133 + 0xb octets C#
[Code externe]
Mrnf.Son.Presentation.Windows.exe!Mrnf.Son.Presentation.Windows.Controleurs.Sondages.ActionsSondages.OnImporterSysExt() Ligne 1362 + 0x1f octets C#
Mrnf.Son.Presentation.Windows.exe!Mrnf.Son.Presentation.Windows.UI.Sondages.UEExploitationVue._mniImporterSysExt_Click(object sender = {System.Windows.Forms.ToolStripMenuItem}, System.EventArgs e = {System.EventArgs}) Ligne 820 + 0x12 octets C#
[Code externe]
Mrnf.Son.Presentation.Windows.exe!Mrnf.Son.Presentation.Windows.Program.Main() Ligne 148 + 0x8 octets C#
[Code externe]
编辑3:如果我传递null给ShowDialog它工作正常(UI不冻结,取消按钮工作,它取消罚款).我真的不明白这一切背后的魔力.
其他帖子可能正在说明原因。
当我尝试终止线程时,我喜欢将WaitHandles与 Thread.Join()/Thread.Abort() 结合使用。
private readonly ManualResetEvent _ExitThreadsEvent = new ManualResetEvent(false);
private Thread _MyThread;
public void Stop()
{
_ExitThreadsEvent.Set();
if (_MyThread != null)
{
if (!_MyThread.Join(5000))
{
_MyThread.Abort();
}
_MyThread = null;
}
}
private void MyThread()
{
if (!_ExitThreadsEvent.WaitOne(1))
{
// Do some work...
}
if (!_ExitThreadsEvent.WaitOne(1))
{
// Do some more work...
}
}
Run Code Online (Sandbox Code Playgroud)
不过,弄清楚你原来的僵局问题也可能很好。
| 归档时间: |
|
| 查看次数: |
1203 次 |
| 最近记录: |