我做得对吗? Windows窗体应用程序中的后台工作

时间:2015-12-05 11:48:35

标签: c# .net winforms

我有一个Windows窗体应用程序。按下某个按钮后,我想在后台做一些事情。

//---------- MyWorker::Run
public Task Run()
{
   WorkerTask = Task.Factory.StartNew(() =>
   {
       //Access MyWorker's properties etc. causes complications as it runs from 
       // a different thread and I need to use InvokeRequired etc. but not everything has Invoke method implemented.
   }, TokenSource.Token, TaskCreationOptions.LongRunning, TaskScheduler.Default);

   return WorkerTask;
}

//---------- Form event
async void DoSomething(object sender, EventArgs e)
{
   var task = MyWorker.Run();

   await task;
}

但是,当我尝试在run方法中访问MyWorker的对象时,由于它在不同的线程中运行,因此存在一些复杂性。这里会有什么模式?我在考虑类似的事情:

//---------- Form event
async void DoSomething(object sender, EventArgs e)
{

   Task.Factory.StartNew(() =>
   {
       var MyWorker1 = new MyWorker(...);
       // Worker is synchronous here
       MyWorker1.Run();
   }, TokenSource.Token, TaskCreationOptions.LongRunning, TaskScheduler.Default);
}

但我无法通过其他方法访问MyWorker。提前谢谢..我很困惑。

2 个答案:

答案 0 :(得分:3)

您不应完全按照Task.Run(或StartNew实施方法;相反,使用Task.Run调用方法:

async void DoSomething(object sender, EventArgs e)
{
  var task = Task.Run(() => MyWorker.Run());
  await task;
}

这样,您可以从多种方法访问MyWorker ...当然还有多个线程。然后由你来应用适当的同步。

在旁注中,您不需要在现代应用中使用InvokeBeginInvoke;总有优越的解决方案。例如,await将自动返回UI线程上下文。同样,Progress<T>可以自动同步到UI上下文。

答案 1 :(得分:-2)

您可以自定义此方法:

var myTasks = new ConcurrentBag<Task>();
var myResults = new ConcurrentBag<int>();

并使用它:

myTasks.Add(Task.Factory.StartNew(() =>
{
    //do something
    myResults.Add(5);
});