简体   繁体   English

异步方法调用 - 维护序列

[英]Async Method Invocation - Maintain Sequence

I have series of asyc methods that needs to be called in perticular sequence.我有一系列需要按特定顺序调用的 asyc 方法。 The problem is that, all methods makes request to WCF service.问题是,所有方法都向 WCF 服务发出请求。 Method that makes WCF call is common to whole project.使 WCF 调用的方法对整个项目是通用的。 In the callback function of WCF call, I determine whether WCF call was successful or not.在WCF调用的回调function中,判断WCF调用是否成功。 If WCF call was successful I need to call another method.如果 WCF 调用成功,我需要调用另一个方法。 There are many methods to be called in sequence, one-after-other.有许多方法要按顺序调用,一个接一个。

private Action<string> action;

public void MakeHttpPostRequest(string webserviceURL, string json, Action<string> response)
{
try
{
    this.action = response;

    if (Microsoft.Phone.Net.NetworkInformation.NetworkInterface.GetIsNetworkAvailable())
    {
        Uri uri = new Uri(webserviceURL);
        byte[] byteArray = System.Text.Encoding.UTF8.GetBytes(json);

        string data = Encoding.UTF8.GetString(byteArray.ToArray(), 0, (int)byteArray.Length);
        WebClient webClient = new WebClient();
        webClient.UploadStringCompleted += new UploadStringCompletedEventHandler(this.WebClient_UploadStringCompleted);
        webClient.Headers["Content-type"] = "application/json";
        webClient.Encoding = Encoding.UTF8;
        webClient.UploadStringAsync(uri, "POST", data);
    }
    else
    {
        this.action(string.Empty);
    }
}
catch (Exception ex)
{
    new ErrorException.ErrorException().HandleError(ex, string.Empty, Global.Modules.General);
}
}

private void WebClient_UploadStringCompleted(object sender, UploadStringCompletedEventArgs e)
{
try
{
    // Check whether to invoke any method
    if (this.action != null)
    {
        // Invoke the method passed to MakeHttpPostRequest by it's calling method
        this.action(e.Result);
    }
}
catch (Exception ex)
{
    new ErrorException.ErrorException().HandleError(ex, string.Empty, Global.Modules.General);
}
}

I do not think that writing different callback event for each method and calling next method is good idea.我不认为为每个方法编写不同的回调事件并调用下一个方法是个好主意。

It is really just a different rearranging of code, but you could simply create a queue of "Tasks" that need to be run one after another.这实际上只是代码的一种不同的重新排列,但您可以简单地创建一个需要一个接一个运行的“任务”队列。

That "Task manager" could catch any completion events from each task and start the next task in the queue.该“任务管理器”可以从每个任务中捕获任何完成事件并启动队列中的下一个任务。

The Task interface is up to you, but it just needs a Start method and an OnCompleted event as a minimum, but you will need to handle failures sensibly as well. Task 接口由您决定,但它至少需要一个 Start 方法和一个 OnCompleted 事件,但您还需要明智地处理故障。

Background背景

We did something like this over a year ago as we needed both parallel and sequential tasks to be executed, so built it so that each of our tasks could contain other tasks (our task manager just became a top level task itself).一年多前我们做了类似的事情,因为我们需要执行并行和顺序任务,因此构建它以便我们的每个任务都可以包含其他任务(我们的任务管理器本身就成为顶级任务)。 Your high-level code then just becomes a set of adds on the task manager to create an appropriate ordering of the child tasks followed by a manager call to Start the first task(s).然后,您的高级代码只是成为任务管理器上的一组adds ,以创建子任务的适当顺序,然后是管理器调用以启动第一个任务。

As a guide it is often better to write a complex subsystem (once), that gives you a very simple top level in all your apps, than to keep stitching together code and event handlers.作为指导,通常最好编写一个复杂的子系统(一次),它为您的所有应用程序提供一个非常简单的顶层,而不是继续将代码和事件处理程序拼接在一起。

If I understand what you want correctly, just change your action field to a queue of actions.如果我正确理解您想要什么,只需将您的action字段更改为操作队列。 In WebClient_UploadStringCompleted , write:WebClient_UploadStringCompleted中,写入:

if (actionQueue.Count > 0)
{
    var action = actionQueue.Dequeue();
    action(e.Result);
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM