2013-01-08 21 views
1

我创建了一个非常简单的winform应用程序,它具有单个窗体和一个按钮。其点击事件如下所示进行连线。如果您单击该按钮,该应用程序会按预期运行,即ExecTasks退出。如果通过lock(this)替换锁语句,ExecTasks将不会退出,调试器会在Exec中的代码中的sleep/wait/join中显示一个线程。问题为什么锁定对象的选择会改变这种行为 - 为什么表单实例不是有效的选择?在一个非常简单的winform应用程序中发生死锁

using System; 
using System.Collections.Generic; 
using System.ComponentModel; 
using System.Data; 
using System.Drawing; 
using System.Linq; 
using System.Text; 
using System.Threading.Tasks; 
using System.Windows.Forms; 

namespace TestDeadlock 
{ 
public partial class Form1 : Form 
{ 
    private object _lock = new object(); 
    public Form1() 
    { 
     InitializeComponent(); 
    } 

    private void Button1Click(object sender, EventArgs e) 
    { 
     Task.Factory.StartNew(ExecTasks); 
    } 

    private void ExecTasks() 
    { 
     lock (_lock) /* replace by lock(this) to see the blocked behavior */ 
     { 
      var taskList = new List<Task>(); 
      for (var i = 0; i < 2; ++i) 
      { 
       taskList.Add(Task.Factory.StartNew(Exec)); 
      } 
      Task.WaitAll(taskList.ToArray()); 
     } 
    } 

    private void Exec() 
    { 
     Invoke((Action)delegate{}); 
    } 
} 
} 

回答

2

我看到这种阻塞行为。当你调用Invoke方法,它导致调用Control.FindMarshalingControl方法,其实现如下:

private Control FindMarshalingControl() 
{ 
    lock (this) 
    { 
     Control parentInternal = this; 
     .... 
    } 
} 

下面是一个类似问题的链接:

Control.BeginInvoke will also be blocked

+0

感谢快响应。 –

相关问题