0

enter code here我在 .cs 文件中有这个属性。每当我设置此属性时,与它关联的事件就会被触发。

    public event Action ResponseReceived;
    private string response;

    public string Response
    {

        get
        {
            return response;
        }

        set
        {
                response = value;
                if (ResponseReceived != null) { ResponseReceived(); }
        }

    }

现在的问题是当我这样做时在另一个文件中

ResponseReceived += new Action(function_ResponseReceived);
void function_ResponseReceived()
{
    //change to gui thread
    if (InvokeRequired) 
    {   
        this.BeginInvoke(new Action(function_ResponseReceived), new object[] { }); 
        return; 
    }

    textBox1.Text = Response;
}


Response = "yes";

. . . (几行之后)。. .

Response = "no";

yes不会触发与事件关联的函数,因为Response = "no";总是触发(该Response字段的更新速度比触发事件所需的时间快,所以我猜它被覆盖了)。有没有一种方法可以让我设置属性时与事件相关的函数都正确触发

4

3 回答 3

1

您对 Response 字段的更新速度比触发事件所需的时间更快的分析是不正确的。发生这种情况的唯一方法是,如果ResponseReceived委托在多个线程上更改,在这种情况下,您会遇到竞争条件。如果您查看代码,该方法中的每一步都将在同一个线程上连续执行(即一个接一个)。

必须重置或更改ResponseReceived事件-我的猜测是您在执行任何期望响应的操作之后设置事件处理程序,因此当第一个响应出现时,您尚未设置事件处理程序-在这种情况下,解决方案显然是在触发获取响应的操作之前设置事件处理程序。

于 2013-04-19T08:40:03.827 回答
1

初步答案:

您显示的代码工作正常。
你的代码中一定有你提到的'. . . (几行之后)。. .'.

测试代码:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;    

namespace FunctionAssociatedPropertyFire {
    class Program {
        static void Main(string[] args) {
            new TestClass().Test();
            Console.ReadLine();
        }
    }
    class TestClass {
        public event Action ResponseReceived;
        private string response;    
        public string Response {
            get { return response; }    
            set {
                response = value;
                if (ResponseReceived != null) { ResponseReceived(); }
            }
        }

        void function_ResponseReceived() {
            Console.WriteLine("function_ResponseReceived");
        }

        public void Test() {
            ResponseReceived += new Action(function_ResponseReceived);
            Console.WriteLine("BeforeYes");
            Response = "yes";
            Console.WriteLine("AfterYes");
            Response = "no";
            Console.WriteLine("AfterNo");
        }
    }
}

测试结果:

BeforeYes
function_ResponseReceived
AfterYes
function_ResponseReceived
AfterNo

更新:

您正在异步调用,因此调用代码不会等待被调用的方法完成。您可以尝试使用 Invoke 方法而不是 BeginInvoke 方法。

void function_ResponseReceived() {
    //change to gui thread
    if (InvokeRequired) 
    {   
        this.Invoke(new Action(function_ResponseReceived), new object[] { }); 
        return; 
    }

    textBox1.Text = Response;
}
于 2013-04-19T09:04:43.323 回答
0

只要您不篡改ResponseReceived两行之间的内容,就应该两次调用该操作。没有什么比该方法触发更快地更新该字段。

于 2013-04-19T08:42:59.963 回答