1

一度に最大 4 つのファイルをダウンロードするダウンロード システムで作業しています。ダウンロード中にエラーが発生した場合は、最大 5 回再試行します。ダウンロードが完了したら、変数を使用してさまざまなコールバックを呼び出したいと思います。

これは私が書いたものです:

private void Download(string url, (something) callback)
{
    if (asyncworkers++ < Global.paralleldownloads -1) // async download
    {
        using (WebClient client = new WebClient())
        {
            client.Proxy = (Global.proxymode == 2 ? new WebProxy(dynamicproxy) : (Global.proxymode == 1 ? new WebProxy(Global.proxy) : null));
            System.Timers.Timer timer = new System.Timers.Timer(5000);
            timer.Enabled = true;
            client.DownloadStringCompleted += (sender, e) => 
            {
                asyncworkers--;
                if (timer.Enabled)
                {
                    timer.Stop();
                    if (e.Error == null && e.Result.Length > 0)
                    {
                        AppendTextBox("successful async\r\n");
                        errors = 0;
                        //call "callback" and its variables here
                    }else{
                        AppendTextBox("empty async\r\n");
                        if (errors++ > 3)
                        {
                            //stop trying
                        }else{
                            Download(url, callback);
                        }
                    }
                }
            };
            client.DownloadStringAsync(new Uri(url));
            timer.Elapsed += (sender, e) =>
            {
                AppendTextBox("timeout async\r\n");
                timer.Enabled = false;
                client.CancelAsync();
                Download(url, callback);
            };
        }
    }else{ // sync download to delay it
        var request = WebRequest.Create(url);
        request.Proxy = (Global.proxymode == 2 ? new WebProxy(dynamicproxy) : (Global.proxymode == 1 ? new WebProxy(Global.proxy) : null));
        request.Timeout = 5000;
        using (var response = request.GetResponse())
        {
            using (var stream = response.GetResponseStream())
            {
                using (var reader = new StreamReader(stream))
                {
                    string data = reader.ReadToEnd();
                    if (data.Length > 0)
                    {
                        AppendTextBox("successful sync\r\n");
                        asyncworkers--;
                        errors = 0;
                        //call "callback" and its variables here
                        return;
                    }
                }
            }
        }
        asyncworkers--;
        AppendTextBox("error sync\r\n");
        if (errors++ > 3)
        {
            //stop trying
        }else{
            Download(url, callback);
        }
    }
}

これは私がそれを使用したい方法です:

Download("http://.....", GetDataDone(var1, var2, var3, var4));

また

Download("http://.....", UpdateDone());

私が説明したことが、あなたにとって少なくとも少しは明らかであることを願っています。どうすれば希望どおりに動作させることができますか? ありがとう!

4

1 に答える 1

1

where is が、isなどの型であると宣言callbackします。次のようにコールバックを呼び出します。Action<T1,T2,T3,T4>T1var1T2var2

public void Download(string url, Action<T1,..> callback)
{
    //....
    callback(var1,var2,var3,var4);
    //...
}

一致する署名を持つ関数をコールバックとして名前で渡すか、ラムダを使用して署名を一致させます。

public void OnDownload(T1 var1, T2 var2, T3 var3, T4 var4)
{
     // do stuff here
}

//later
Download("http...", OnDownload);

コメント後に更新

ラムダ式を使用して引数を事前に渡します。

public void Download(string url, Action callback)
{
     //...
     callback();
     //..
}


 Download("http://..", () => OnDownload(42, "request", user, 0.5f));
于 2013-11-10T18:23:01.407 に答える