0


私は ac# user-control @ work を開発しています。コントロールは、いくつかの情報とデータをロードして表示するだけです。
今、私はコントロールのユーザーにデータ非同期をロードするオプションを提供したいと思います..次のようにsmth:

Cntrl.LoadSmthAsync(..)
Cntrl.LoadSmthComplete   //EventHandler to give feedback if the Load was successfull.

ダウンロード関数を非同期にし、EventHandlers を介して戻り値を提供することにしました。
しかし、そのコードはかなり複雑になりました..結局のところ。

ここで、コントロールが何をすべきかを理解するためのいくつかのコード:

    public byte[] LoadByPos(int pos)
    {
        string url = Pos2Url(pos);

        // update gui
        this.textBox1.Text = url;

        byte[] res = LoadByUrl(url);

        // update gui
        this.textBox2.Text = BytesToString(res);

        return res;
    }

    public byte[] LoadByUrl(string url)
    {
        return Download(url);
    }

    //primary problem: download function
    private byte[] Download(string url)
    {
        System.Threading.Thread.Sleep(1000 * 30);
        return StringToBytes(url);
    }

    //secondary problem: an other function
    private string Pos2Url(int pos)
    {
        System.Threading.Thread.Sleep(1000 * 5);
        return pos.ToString();
    }




    // LoadByPosAsync
    public delegate void LoadByPosDoneHandler(Object sender, byte[] e);
    public event LoadByPosDoneHandler LoadByPosDone;

    public void LoadByPosAsync(int pos)
    {
        string url = Pos2Url(pos);

        // update gui
        this.textBox1.Text = url;

        LoadByUrlDone += new LoadByUrlDoneHandler(LoadByPosAsync_LoadByUrlDone);
        LoadByUrlAsync(url);
    }
    public void  LoadByPosAsync_LoadByUrlDone(object sender, byte[] e)
    {
        // update gui
        this.textBox2.Text = BytesToString(e);

        LoadByUrlDone = null;
        LoadByPosDone(sender, e);
    }


    //LoadByUrlAsync

    public delegate void LoadByUrlDoneHandler(Object sender, byte[] e);
    public event LoadByUrlDoneHandler LoadByUrlDone;

    public void LoadByUrlAsync(string url)
    {
        DownloadDone += new DownloadDoneHandler(LoadByUrlAsync_DownloadDone);
        DownloadAsync(url);
    }
    private void LoadByUrlAsync_DownloadDone(object sender, byte[] e)
    {
        LoadByUrlDone(sender, e);
    }

    //DownloadAsync

    private delegate void DownloadDoneHandler(Object sender, byte[] e);
    private event DownloadDoneHandler DownloadDone;

    private void DownloadAsync(string url)
    {
        BackgroundWorker bw_DownloadAsync = new BackgroundWorker();
        bw_DownloadAsync.RunWorkerCompleted += new RunWorkerCompletedEventHandler(bw_DownloadAsync_RunWorkerCompleted);
        bw_DownloadAsync.DoWork += new DoWorkEventHandler(bw_DownloadAsync_DoWork);
        bw_DownloadAsync.RunWorkerAsync(url);
    }
    void bw_DownloadAsync_DoWork(object sender, DoWorkEventArgs e)
    {
        byte[] res = Download((string)e.Argument);
        e.Result = res;
    }
    void bw_DownloadAsync_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
    {
        DownloadDone(sender, (byte[])e.Result);
    }

私がやろうとしていることを達成するためのより簡単な方法はありますか?

thx事前に

4

1 に答える 1

0

私がやろうとしていることを達成するためのより簡単な方法はありますか?

実装面は別にありますが、.NET 4を使用している場合は、このモデルを非同期に使用しないことを強くお勧めします。イベントハンドラーを使用するのではなく、を使用することをお勧めしますTask<T>TaskCompletionSource固有のサポートがない場合は、を使用してタスクを作成できます。これは、非同期/待機サポートにより、APIがC#5ではるかに使いやすくなることを意味します。その時点で、UIスレッドメソッドは次のようになります。

public async Task<byte[]> LoadByPos(int pos)
{
    string url = await Pos2UrlAsync(pos);

    // update gui
    this.textBox1.Text = url;

    byte[] res = await LoadByUrlAsync(url);

    // update gui
    this.textBox2.Text = BytesToString(res);

    return res;
}

非同期は、コードを自然に流れるだけです。

于 2012-05-19T09:22:18.087 に答える