Asynchronous call with a static method in C# .NET 2.0

元气小坏坏 提交于 2019-12-13 00:08:10

问题


I have a .NET 2.0 application. In this application, I need to pass data back to my server. The server exposes a REST-based URL that I can POST data to. When I pass data back to my server, I need to sometimes do so asynchronously, and other times I need a blocking call. In the scenario of the asynchronous call, I need to know when the call is completed. Everything up to this point I understand how to do.

Where I get into trouble is, the method that I am working on MUST be static. It's code I've inherited, and I'd rather not have to redo all of this code. Currently, I have two static methods:

public static string SendData (...) {
}

public static string SendDataAsync(...) {

}

The string returned is a response code from the server. The static part is giving me fits. It doesn't cause a problem in my blocking version. However, in the contest of the asynchronous call, I'm not sure what to do.

Does anyone have any insights they can provide?


回答1:


This is the general async pattern before C# 5 (IIRC).

public static string SendData (...) {
}

public static IAsyncResult BeginSendData(..., AsyncCallback cb) {
   var f = new Func<..., string>(SendData);
   return f.BeginInvoke(..., cb, f);
}

public static string EndSendData(IAsyncResult ar) {
   return ((Func<..., string>) ar.AsyncState).EndInvoke(ar); 
}

Usage:

BeginSendData(..., ar => 
   {
     var result = EndSendData(ar);
     // do something with result
   });

Full console example:

public static string SendData(int i)
{
    // sample payload
    Thread.Sleep(i);
    return i.ToString();
}

public static IAsyncResult BeginSendData(int i, AsyncCallback cb)
{
    var f = new Func<int, string>(SendData);
    return f.BeginInvoke(i, cb, f);
}

public static string EndSendData(IAsyncResult ar)
{
    return ((Func<int, string>)ar.AsyncState).EndInvoke(ar);
}

static void Main(string[] args)
{
    BeginSendData(2000, ar => 
        {
            var result = EndSendData(ar);
            Console.WriteLine("Done: {0}", result);
        });

    Console.WriteLine("Waiting");
    Console.ReadLine();
}

The above will print:

Waiting
Done: 2000



回答2:


Create a class wrapping your service calls. From that only call the static blocking method, but call it from a background thread. Then execute a callback or raise an event once the service call returned:

public class CompletedEventArgs : EventArgs
{
    public string Result { get; set; }
}

public class MyServiceWrapper
{
    public event EventHandler<CompletedEventArgs> CallCompleted;

    public string SendData()
    {
        return StaticService.SendData();
    }

    public void SendDataAsync()
    {
        ThreadPool.QueueUserWorkItem(state => {
            var result = StaticService.SendData();
            var handler = CallCompleted;
            if (handler != null)
            {
                handler(this, new CompletedEventArgs{ Result = result });
            }
        });
    }
}

Keep in mind though that the event that gets raised does not come from the UI-thread, thus you have to dispatch it accordingly when you want to react to it in a UI.



来源:https://stackoverflow.com/questions/14815984/asynchronous-call-with-a-static-method-in-c-sharp-net-2-0

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!