开发者

need help accessing data coming off a callback C# .NET

I'm at my wits end trying to solve this issue.

I have a function in a class as such

p开发者_StackOverflow社区ublic 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
    }
}

That's simple. However, what would I do if AllData function had to make async function calls to get data?

Meaning, say

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.
    }

As you can see, now I cant simply call AllData function and directly get data back.

So, what would I have to do in ResponseData function to make sure I call the AllItem function, and get data back from the callback. Notice that there's a loop in that function, so I need to all the parameters I have sent through the loop gets respective response.

One approach I tried was by using AutoResetEvent class.

I defined a handler for this as AutoResetEvent handle = new AutoResetHandle(false);

then I add handle.WaitOne() right after the async call. and on the callback, added handle.Set();

However, the applications get stuck at handle.WaitOne(). So I can't really see why that happens.

I now have a theoritical idea to see if I could have a event raiser on the callback, and an eventlistener in RecieveData class, and if those two communicate, I could get the data. But I've spent some time trying to learn more about event handlers, but haven't gotten the hang of it.

So does anybody have any other approach, ideas? Thanks!


Welcome to the asynchronous model. You have to re-think how you call methods when you go multithreaded.

You have some options:

  • Split the method in which you're making the call into two halves; in the first half, call AllData, do ANYTHING else you can possibly do without having the response object, and then exit your current method. When the async call completes, it'll call your handler, where you should perform all operations from the original method that require the response.

  • In the event handler for the async call completion, set a property that indicates the call is completed, and put the data out on a property somewhere as well. In the function that kicks off the call, at the point where you simply cannot continue execution until the call completes, wait in a while loop for the call to complete by polling the property and breaking once it indicates the call has been completed (you'll probably want a Thread.Yield() in the loop as well that you'll call when you haven't gotten a response yet, to make sure you aren't blocking other threads doing more important things than waiting)

  • Wrap your asynchronous call in a class that exposes a synchronous method. The wrapper class will have similar logic as integrating the async call into your method. It will make the call, wait for the response, and return that response as if it were a normal synchronous method call.

Remember that the asynchronous call is giving your calling thread the opportunity to do other work while the call is performed. Take full advantage of this if at all possible.


You just need to use a delegate and call BeginInvoke. You can then set a callback method to capture the result of the delegate call.

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);
    }
}
0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜