我正在尝试使用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()方法,这样我就可以将搜索结果添加到面板中。
答案 0 :(得分:2)
您无需将UI元素“传递”到ContinueWith
方法中;捕获局部变量甚至直接访问实例变量都没问题。
但是,您需要确保您的ContinueWith
委托在UI线程上执行。您只需使用an overload that takes a 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
属性。
答案 1 :(得分:1)
可能你不需要传递它们。您可以在lambda函数中简单地引用它们。请注意,您必须使用Invoke或Dispatcher来访问其他线程中的UI元素。
每个在不同lambda函数之间“共享”的变量必须在外部 lambda函数声明(闭包!!!!)。
答案 2 :(得分:1)
您不需要将变量(控件)传递给continuation;只是在延续代码中正常访问它们。
但是当线程访问控件时,您将获得跨线程异常。要防止这种情况,请在UI线程上运行continuation:
.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()
可确保将继续传递回主线程。