Tag: 同步

如何在收到异步函数回调之前hibernate一个线程?

我有一个只有在从异步函数收到回调时才需要执行的函数。 喜欢 我调用异步函数Stop() ,不久之后我调用异步函数Start() 。 收到Stop CallBack之前的问题调用Start()被调用,因此我遇到了问题。 另外我无法分开两个函数的调用,就像我不能这样做: public void SomeFunction() { Stop(); } public void Stop_CallBack(eventargs e) { Start(); } 我必须这样做: public void SomeFunction() { Stop(); //Do something; Start(); } 但在我收到停止回叫之前,我的start()函数被执行,从而为我创造了问题。 任何人都可以帮助我如何解决这个问题。

从库中捕获主线程SynchronizationContext或Dispatcher

我有一个C#库,希望能够发送/发布工作到“主”ui线程(如果存在)。 该库可用于: 一个winforms应用程序 本机应用程序(使用UI) 控制台应用程序(没有UI) 在库中我想在初始化期间捕获一些东西(A SynchronizationContext,Dispatcher,Task Scheduler或其他东西),这将允许我(稍后)发送/发布工作到主线程(如果主线程有这种能力 – 即它有一个消息泵)。 例如,当且仅当主应用程序能够访问主线程时,库才会在主线程上放置一些Winforms UI。 我尝试过的事情: 一个SynchronizationContext :捕获它适用于Winforms应用程序( WindowsFormsSynchronizationContext将作为当前 SynchronizationContext安装。这也适用于控制台应用程序 – 因为我可以检测到当前SynchronizationContext为null(因此,知道我不知道)没有能力发送/发布工作到主线程。这里的问题是本机UI应用程序:它有能力(即它有一个消息泵),但当前同步上下文为空,因此我可以’将它与Console应用案例区分开来。如果我可以区分,那么我可以在主线程上安装一个WindowsFormsSynchronizationContext,我很高兴。 Dispatcher :使用Current捕获它会创建一个新的SynchronizationContext。 因此,在所有情况下,我都会找回Dispatcher。 但是,对于Console应用程序,从后台线程使用Dispatcher.Invoke将挂起(如预期的那样)。 我可以使用Dispatcher.FromThread (如果不存在,则不会为该线程创建Dispatcher)。 但是本机UI应用程序将使用此方法返回null Dispatcher,因此我再次陷入无法区分UI应用程序与控制台应用程序的问题。 TaskScheduler :我可以使用FromCurrentSynchronizationContext 。 这与SynchronizationContext具有相同的问题。 即在调用FromCurrentSyncronizationContext之前,我必须检查当前SynchronizationContext是否为null(对于Console应用程序和本机ui应用程序将是这种情况)。 所以,我再次无法将本机ui应用程序与控制台应用程序区分开来。 当然,我可以让我的库的用户在调用我的Initialize方法时指定它是否是一个UI应用程序,但我希望尽可能避免该库的用户的复杂性。

lock语句如何确保内部处理器同步?

我有一个小型测试应用程序,它同时执行两个线程。 一个增加static long _value ,另一个递减它。 我已经确保使用ProcessThread.ProcessorAffinity ,线程与不同的物理(无HT)内核相关联,以强制进行内部处理器通信,并确保它们在执行时间内重叠了很长时间。 当然,以下不会导致零: for (long i = 0; i < 10000000; i++) { _value += offset; } 因此,合乎逻辑的结论是: for (long i = 0; i < 10000000; i++) { Interlocked.Add(ref _value, offset); } 这当然导致零。 但是,以下也导致零: for (long i = 0; i < 10000000; i++) { lock (_syncRoot) { _value += offset; […]

在try中通过锁定锁定资源。 这是错的吗?

使用带有try块的锁有什么问题吗? 我记得在某个地方读过我们应该总是尝试在try块中放入最少量的代码并在内部锁定自己使用try-finally块,你们在这里看到了什么错误。我需要处理锁内的代码这一事实块可以抛出exception try { lock(syncblk) { // do some processing } } catch(Exception e) { // do something with exception }

不明白需要Monitor.Pulse()

根据MSDN , Monitor.Wait() : 释放对象的锁定并阻止当前线程,直到它重新获取锁定。 但是,我所读到的关于Wait()和Pulse()的所有内容似乎表明仅仅释放另一个线程上的锁是不够的。 我需要先调用Pulse()来唤醒等待的线程。 我的问题是为什么? 在Monitor.Enter()上等待锁定的线程只是在它被释放时获取它。 没有必要“唤醒他们”。 它似乎打败了Wait()的有用性。 例如。 static object _lock = new Object(); static void Main() { new Thread(Count).Start(); Sleep(10); lock (_lock) { Console.WriteLine(“Main thread grabbed lock”); Monitor.Pulse(_lock) //Why is this required when we’re about to release the lock anyway? } } static void Count() { lock (_lock) { int […]

我需要Dispose()或Close()一个EventWaitHandle吗?

如果我使用EventWaitHandle (或AutoResetEvent , ManualResetEvent )来在线程之间进行同步,那么当我完成它时,是否需要在该事件句柄上调用Close()或Dispose()方法? EventWaitHandleinheritance自WaitHandle ,后者实现了IDisposable 。 如果我没有在任何包含EventWaitHandle类上实现IDisposable ,FxCop会抱怨。 所以这表明我确实需要打电话给它。 但是,这些MSDN用法示例都没有调用Dispose()或Close() : http://msdn.microsoft.com/en-us/library/system.threading.eventwaithandle(VS.80).aspx http://msdn.microsoft.com/en-us/library/system.threading.manualresetevent( VS.80).aspx http://msdn.microsoft.com/en-us/library/system.threading.autoresetevent(VS.80).aspx 这只是微软无视自己建议的一个例子吗?

C#具有异步函数调用同步函数或同步函数调用异步函数

我正在编写一个C#.Net 4.5库,用于执行常见的sql数据库操作(备份,恢复,执行脚本等)。 我希望每个操作都有同步和异步函数,因为这个库将由控制台和GUI应用程序使用,但我不想在任何地方重复代码。 所以我看到它,我有两个选择: 编写在同步函数中执行工作的代码,然后将其包装在async函数的任务中,如下所示: public void BackupDB(string server, string db) { // Do all of the work and long running operation here } public async Task BackupDBAsync(string server, string db) { await Task.Factory.StartNew(() => BackupDB(server, db)).ConfigureAwait(false); } 编写在异步函数中执行工作的代码,并使用.Wait()从同步函数中调用它: public async Task BackupDBAsync(string server, string db) { // Do all of the work and long […]

为什么LogicalCallContext无法与异步一起使用?

在这个问题中,Stephen Cleary接受的答案是LogicalCallContext无法与async一起正常工作。 他还在这个 MSDN主题中发布了它。 LogicalCallContext保持Hashtable存储发送到CallContext.LogicalGet / SetData的数据。 它只是这个Hashtable的浅层副本。 因此,如果您在其中存储可变对象,则不同的任务/线程将看到彼此的更改。 这就是Stephen Cleary的示例NDC程序(在MSDN线程上发布)无法正常工作的原因。 但是AFAICS,如果你只在Hashtable中存储不可变数据(可能通过使用不可变集合 ),那应该有效,让我们实现一个NDC。 然而,Stephen Cleary也在接受的答案中说: CallContext不能用于此。 Microsoft特别建议不要使用CallContext进行远程处理以外的任何操作。 更重要的是,逻辑CallContext不了解异步方法如何提前返回并稍后恢复。 不幸的是,该建议的链接已关闭(找不到页面)。 所以我的问题是,为什么不推荐这个? 为什么我不能以这种方式使用LogicalCallContext? 说它不理解异步方法是什么意思? 从调用者的POV来看,他们只是返回任务的方法,不是吗? ETA:另见其他问题 。 在那里,Stephen Cleary的答案说: 你可以使用CallContext.LogicalSetData和CallContext.LogicalGetData,但我建议你不要,因为当你使用简单的并行性时它们不支持任何类型的“克隆” 这似乎支持我的情况。 所以我应该能够建立一个NDC,这实际上是我需要的,而不是log4net。 我写了一些示例代码,它似乎工作,但仅仅测试并不总是捕获并发错误。 所以,由于其他post中有提示这可能不起作用,我仍然会问:这种方法有效吗? ETA:当我从下面的答案中运行斯蒂芬提出的复制品时,我没有得到错误的答案,他说我会,我得到正确的答案。 即使他说“这里的LogicalCallContext值总是”1“”,我总是得到0的正确值。这可能是因为竞争条件? 无论如何,我还没有在我自己的电脑上复制任何实际问题。 这是我正在运行的确切代码; 它只在这里打印“真实”,斯蒂芬说它至少应该在某些时候打印“假”。 private static string key2 = “key2”; private static int Storage2 { get { return (int) CallContext.LogicalGetData(key2); } set […]

C#,System.Timers.Timer,每15分钟与系统时钟同步运行

如何让System.Timers.Timer每15分钟触发一次与系统时钟同步的Elapsed事件? 换句话说,我希望它完全触发xx:00,xx:15,xx:30,xx:45(其中xx表示任何小时)

C#中两个进程之间的同步。

有什么方法可以让我们同步两个独立的进程吗? 就像他们共享资源一样,我想同步它们。 我正在使用C#。