需要帮助访问来自回调C#.NET的数据

时间:2010-11-16 15:20:59

标签: c# .net asynchronous

我最终试图解决这个问题。

我在类中有一个函数

public class ReceiveData
{
    Dataprovider provider = new DataProvider();

    public void ResponseData()
    {
        foreach(string anItem in TheList)
        {
            // AllData function is declared in class DataProvider
            string result = provider.AllData(anItem); 
        }

        //do something
    }
}

这很简单。但是,如果AllData函数必须进行异步函数调用以获取数据,我该怎么办?

意思,说

public class DataProvider 
{
    MyServiceClient client = new MyServiceClient();

    public string AllData (string  myItem)
    {
        client.FormattedDataCompleted += new EventHandler<FormattedDataCompletedEventArgs>(client_FormattedDataCompleted);
        client.FormattedDataAsync(myItem);
    }

    void client_FormattedDataCompleted(object sender, FormattedDataCompletedEventArgs e)
    {
        // here's where the response comes back.
    }

如您所见,现在我无法简单地调用AllData函数并直接获取数据。

那么,我需要在ResponseData函数中做些什么来确保我调用AllItem函数,并从回调中获取数据。请注意,该函数中有一个循环,所以我需要通过循环发送的所有参数都得到相应的响应。

我尝试过的一种方法是使用AutoResetEvent类。

我为此定义了一个处理程序 AutoResetEvent handle = new AutoResetHandle(false);

然后我在异步调用之后立即添加handle.WaitOne()。并在回调中添加了handle.Set();

然而,应用程序陷入了handle.WaitOne()。所以我真的不明白为什么会这样。

我现在有一个理论上的想法,看看我是否可以在回调上有一个事件提升器,以及RecieveData类中的eventlistener,如果这两个进行通信,我就可以得到数据。但我花了一些时间试图了解更多有关事件处理程序的知识,但还没有掌握它。

那么有没有人有任何其他方法,想法?谢谢!

2 个答案:

答案 0 :(得分:0)

欢迎使用异步模型。当你进入多线程时,你必须重新考虑如何调用方法。

你有一些选择:

  • 将您拨打电话的方法分成两部分;在上半部分,调用AllData,在没有响应对象的情况下执行其他任何操作,然后退出当前方法。当异步调用完成时,它将调用您的处理程序,您应该在其中执行需要响应的原始方法的所有操作。

  • 在异步调用完成的事件处理程序中,设置一个指示调用已完成的属性,并将数据也放在某个属性的某个位置。在启动呼叫的功能中,在呼叫完成之前您无法继续执行的时间点,等待一个while循环以通过轮询属性完成呼叫,并在一旦它指示呼叫已完成时断开(你' ll可能还需要一个循环中的Thread.Yield(),当你还没有得到响应时你会调用它,以确保你没有阻止其他线程执行比等待更重要的事情。

  • 将异步调用包装在公开同步方法的类中。包装类将具有与将异步调用集成到方法中类似的逻辑。它将进行调用,等待响应,并返回该响应,就像它是正常的同步方法调用一样。

请记住,异步调用使您的调用线程有机会在执行调用时执行其他工作。如果可能的话,充分利用这一点。

答案 1 :(得分:0)

您只需要使用委托并调用BeginInvoke。然后,您可以设置一个回调方法来捕获委托调用的结果。

public class ReceiveData
{
    private List<string> TheList = new List<string>
    {
        "1", "2", "3"
    };

    dynamic provider = new ExpandoObject();

    public void ResponseData()
    {
        foreach (string anItem in TheList)
        {
            // AllData function is declared in class DataProvider
            Func<string, string> asyncAllData = provider.AllData;
            asyncAllData.BeginInvoke(anItem, AllDataDone, null);
        }
        //do something
    }

    private void AllDataDone(IAsyncResult iar)
    {
        AsyncResult ar = (AsyncResult)iar;
        var del = (Func<string, string>)ar.AsyncDelegate;
        // here's your result
        string result = del.EndInvoke(iar);
    }
}