1

我有一个 .NET 2.0 应用程序。在这个应用程序中,我需要将数据传回我的服务器。服务器公开了一个基于 REST 的 URL,我可以将数据发布到该 URL。当我将数据传回我的服务器时,有时我需要异步执行此操作,有时我需要阻塞调用。在异步调用的场景下,我需要知道调用何时完成。到目前为止,我都明白该怎么做。

我遇到麻烦的地方是,我正在使用的方法必须是静态的。这是我继承的代码,我宁愿不必重做所有这些代码。目前,我有两种静态方法:

public static string SendData (...) {
}

public static string SendDataAsync(...) {

}

返回的string是来自服务器的响应代码。静态部分让我很适应。它不会导致我的阻塞版本出现问题。但是,在异步调用的较量中,我不知道该怎么办。

有没有人可以提供任何见解?

4

2 回答 2

0

创建一个包装您的服务调用的类。从那里只调用静态阻塞方法,但从后台线程调用它。然后在服务调用返回后执行回调或引发事件:

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

请记住,尽管引发的事件并非来自 UI 线程,因此当您想在 UI 中对其做出反应时,您必须相应地调度它。

于 2013-02-11T16:19:59.717 回答
0

这是 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); 
}

用法:

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

完整的控制台示例:

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

以上将打印:

Waiting
Done: 2000
于 2013-02-12T12:58:28.113 回答