0

を使用して、いくつかの変数をスレッド アクションに渡そうとしていますTask.Factory.StartNew();。これはコード例です:

Task.Factory.StartNew(() =>
    {
        WebClient webClient = new WebClient();
        string source = webClient.DownloadString("http://localhost/?search=" + search_string);
        return source;
    })
.ContinueWith(result =>
    {
        search_string = search.Text;
        search_string = HttpUtility.UrlEncode(search_string, Encoding.UTF8).Replace("+", "%20");
    });

グループボックスとパネルを ContinueWith() メソッドに渡して、検索結果をパネルに追加できるようにします。

4

3 に答える 3

3

ContinueWithUI 要素をメソッドに「渡す」必要はありません。ローカル変数をキャプチャしたり、インスタンス変数に直接アクセスしたりしても問題ありません。

ContinueWithただし、デリゲートが UI スレッドで実行されるようにする必要があります。これは、 を受け取るオーバーロードをTaskScheduler使用して、によって返されるスケジューラを指定するだけで簡単に実現できますFromCurrentSynchronizationContext

Task.Factory.StartNew(() =>
    {
        WebClient webClient = new WebClient();
        string source = webClient.DownloadString(
            "http://localhost/?search=" + search_string);
        return source;
    })
.ContinueWith(antecedent =>
    {
        // Example use of result:
        this.resultTextBox.Result = antecedent.Result;
    },
    TaskScheduler.FromCurrentSynchronizationContext());

ContinueWithデリゲートに渡されるパラメーターは、その結果ではなく、継続元タスクであることを忘れないでください。結果を取得するには、そのResultプロパティを使用します。

于 2012-05-28T18:41:23.417 に答える
1

変数 (コントロール) を継続に渡す必要はありません。継続コードで通常どおりアクセスするだけです。

ただし、スレッドがコントロールにアクセスすると、クロススレッド例外が発生します。これを防ぐには、UI スレッドで継続を実行します。

.ContinueWith(result => 
    { 
        search_string = search.Text; 
        search_string = HttpUtility.UrlEncode(search_string, Encoding.UTF8).Replace("+", "%20"); 
        // update the UI here (result.Result will contain the return value from the task)        
    }, 
    TaskScheduler.FromCurrentSynchronizationContext());

渡すTaskScheduler.FromCurrentSynchronizationContext()ことで、継続がメインスレッドにディスパッチされます。

于 2012-05-28T18:41:56.117 に答える