2011-12-06 19 views
0

这是我参与工作的老同学WinForms应用程序,他们的设计是使用的模式如下:锁定一个线程是否是一个很好的习惯,以便在winforms中进行事务处理?

每当你需要做的事情的事务,一个操作是在自己的线程中执行,并且线程被锁定(每个操作使用一个特定的锁对象),然后调用wcf服务,一些本地对象被更新,然后锁被释放。

这是一个很好的做法吗?

+0

如果只有“本地”对象按照你说的那样更新,那么你为什么锁定?我认为我们需要更多的信息。代码总是有帮助的。 –

+0

只要你不会造成死锁或将代码转换为spagetti,当然你可以做到这一点。 – Tudor

回答

1

是的,但要小心多线程,并有一个很好的阅读,因为太多的锁可能会造成死锁的情况。

0

我不太清楚你的意思,“锁定一个线程”。是这样的吗?

static object ThreadLock = new object(); 

void ThreadProc(object state) 
{ 
    lock (ThreadLock) 
    { 
     // do stuff here 
    } 
} 

如果是这样,那么这个设计没有什么错。你的UI线程会产生一个应该执行该代码的线程,并且该锁可以防止多个线程同时执行。这有点浪费,因为你可能有许多线程在锁后面排队,但实际上你可能没有超过一个或两个线程在等待。有更有效的方法来实现它(实现某种类型的任务队列),但是你拥有的是简单而有效的。

0

只要你没有等待多个锁对象,这应该没问题。当你有这样的情况发生死锁:

线程A:

lock (lockObject1) 
{ 
    // Do some stuff 

    lock (lockObject2) 
    { 
     // Do some stuff 
    } 
} 

线程B:

lock (lockObject2) 
{ 
    // Do some stuff 

    lock (lockObject1) 
    { 
     // Do some stuff 
    } 
} 

如果你碰巧在线程A锁定lockObject1,而线程B锁定lockObject2前线程A锁定它,那么这两个线程将等待一个锁定在另一个线程中的对象,并且两个线程都不会解锁,因为每个线程在锁定对象时都在等待。这是一个过于简单的例子 - 在这种情况下可能有很多方法。

为避免死锁,不要在锁定第一个对象时等待第二个对象。如果像这样一次锁定一个对象,则不会发生死锁,因为最终,锁定线程将释放等待线程所需的对象。因此,例如,上面应该展开:

线程A:

lock (lockObject1) 
{ 
     // Do some stuff 
} 

lock (lockObject2) 
{ 
     // Do some stuff 
} 

线程B:

lock (lockObject2) 
{ 
     // Do some stuff 
} 

lock (lockObject1) 
{ 
     // Do some stuff 
} 

在这种情况下,每个锁定操作将完成,而不试图收购另一资源,并避免死锁。

0

这不会使动作事务性。我将这意味着整个操作成功或者它不起作用 - 如果我在同步块中更新两个本地对象,第二个错误不会将更改回滚到第一个。

另外,主线程在更新时不会使用这两个对象 - 它需要通过锁定来协作。

在后台线程中锁定仅在您在主线程中使用这些对象时锁定时才有意义。

相关问题