Tag: 闭包

使用闭包而不是锁用于共享状态的优缺点是什么?

我正在尝试评估什么是在单作者单读者场景中共享状态的最快解决方案,其中读者只消耗作者分配的状态变量的最新值。 共享状态可以是任何托管类型(即引用或值类型)。 理想情况下,同步解决方案的工作速度与尽可能简单的非同步解决方案一样快,因为该方法可能会用于单线程和multithreading场景,可能需要数千次。 读取/写入的顺序无关紧要,只要读取器在某个时间范围内接收到最新值(即读取器只能读取,永远不会修改,因此更新时间无关紧要,只要它没有接收到旧价值之前的未来价值…) 天真的解决方案,没有锁定: var memory = default(int); var reader = Task.Run(() => { while (true) { func(memory); } }); var writer = Task.Run(() => { while (true) { memory = DateTime.Now.Ticks; } }); 天真解决方案的问题究竟是什么? 到目前为止我已经想到了这些: 无保证读者看到最新值(没有内存屏障/易失性) 如果共享变量的类型不是基本类型或引用类型(例如,复合值类型),则读取器消耗的值可能无效。 直接的解决方案是锁定: var gate = new object(); var memory = default(int); var reader = Task.Run(() => { […]

改善财产监控代码?

我在C#游戏中制作了一个实用程序调试类,我正在努力监视和查看属性值。 是这样的: public static class Monitor { private static List monitoredObjects; public static void Initialize() { monitoredObjects = new List(); } public static void Watch(object o) { monitoredObjects.Add(o); } public static void Unwatch(object o) { monitoredObjects.Remove(o); } public static void Draw(RenderWindow app) { //Not actual code, I actually draw this in game foreach (object o […]

C#中代理问题

在下面的程序中,DummyMethod总是打印5.但是如果我们使用注释代码,我们会得到不同的值(即1,2,3,4)。 任何人都可以解释为什么会这样吗? delegate int Methodx(object obj); static int DummyMethod(int i) { Console.WriteLine(“In DummyMethod method i = ” + i); return i + 10; } static void Main(string[] args) { List methods = new List(); for (int i = 0; i < 5; ++i) { methods.Add(delegate(object obj) { return DummyMethod(i); }); } //methods.Add(delegate(object obj) { return […]

启动线程时的不同行为:ParameterizedThreadStart与Anonymous Delegate。 为什么这有关系?

当我运行下面的代码时,输​​出是“DelegateDisplayIt”,通常重复1-4次。 我已经运行了这个代码大概100次,并且没有一次输出曾经是“ParameterizedDisplayIt”。 因此,似乎创建并随后启动线程的方式会影响参数的传递方式。 使用匿名委托创建新线程时,该参数是对原始变量的引用,但是当使用ParameterizedThreadStart委托创建时,该参数是一个全新的对象? 我的假设是否正确? 如果是这样,这似乎是线程构造函数的一个奇怪的副作用,不是吗? static void Main() { for (int i = 0; i < 10; i++) { bool flag = false; new Thread(delegate() { DelegateDisplayIt(flag); }).Start(); var parameterizedThread = new Thread(ParameterizedDisplayIt); parameterizedThread.Start(flag); flag = true; } Console.ReadKey(); } private static void DelegateDisplayIt(object flag) { if ((bool)flag) Console.WriteLine("DelegateDisplayIt"); } private static void ParameterizedDisplayIt(object […]

.NET中的multithreading和闭包

如果我有这个: public string DoSomething(string arg) { string someVar = arg; DoStuffThatMightTakeAWhile(); return SomeControl.Invoke(new Func(() => someVar)); } 并且这个方法可以从多个线程同时调用,并且一个线程停留在DoStuffThatMightTakeAWhile ,然后第二个线程调用具有不同arg DoSomething ,这将改变所有线程的someVar的值,因此, DoSomething返回第二个版本的两个调用中的someArg ,或者每个线程someVar存在一个someVar吗? 编辑我认为我的Action应该是一个Func所以编辑它。

C#事件处理程序委托中的闭包?

我现在来自function编程背景,如果我不理解C#中的闭包,请原谅我。 我有以下代码来动态生成获取匿名事件处理程序的按钮: for (int i = 0; i < 7; i++) { Button newButton = new Button(); newButton.Text = "Click me!"; newButton.Click += delegate(Object sender, EventArgs e) { MessageBox.Show("I am button number " + i); }; this.Controls.Add(newButton); } 我期望文本”I am button number ” + i在for循环的迭代中用i的值关闭。 但是,当我实际运行程序时,每个Button都说I am button number 7 。 我错过了什么? 我正在使用VS2005。 编辑:所以我想我的下一个问题是,如何捕捉价值?

如何将多个方法(带参数)作为参数传递?

假设我有以下WCF代码: try { ServiceClient proxy = new ServiceClient(); proxy.ClientCredentials.UserName.UserName = “user”; proxy.ClientCredentials.UserName.Password = “password”; proxy.GetData(2); if (proxy.State = CommunicationState.Opened) { proxy.GetData(“data”); } proxy.Close(); } catch (FaultException ex) { // handle the exception } 而且由于我注意到try … catch和其他逻辑是重复的,更不用说设置WCF调用是昂贵的,我想向这个函数发送许多“方法和参数”。 实质上将GetData(2)和GetData(“data”)作为方法数组传递,并使结果异步或同步返回。 我怎么做到这一点? 我想我可以有两个’ref’对象来处理结果[]和对结果[]的共享锁。 但是我不确定如何将“带参数的方法”作为参数传递给另一个函数。 也许另一种看待它的方法可能是一个函数指针数组,使用不同的参数来表示相同的函数。 任何人都可以推动我做正确的方法吗? 更多信息: 我问这个问题所以我可以优化这种方法来处理WCFexception和重试,但所以我不必总是在每次调用后打开/关闭客户端。

如何在lambda表达式中捕获外部变量的值?

我刚刚遇到以下行为: for (var i = 0; i { Debug.Print(“Error: ” + i.ToString()); }); } 将导致一系列“错误:x”,其中大多数x等于50。 同理: var a = “Before”; var task = new Task(() => Debug.Print(“Using value: ” + a)); a = “After”; task.Start(); 将导致“使用价值:之后”。 这显然意味着lambda表达式中的串联不会立即发生。 在声明表达式时,如何在lambda表达式中使用外部变量的副本? 以下内容不会更好(我承认这不一定是不连贯的): var a = “Before”; var task = new Task(() => { var a2 = a; Debug.Print(“Using […]