其他类的线程化方法?

时间:2012-06-27 06:20:09

标签: c# winforms multithreading

在我的程序中有一个连续调用的方法,因此我想对其进行处理,以便GUI在其业务开展时不会冻结。

Thread t = new Thread(Class2.ArrayWorkings(1, MyGlobals.variable1));
    t.start();
        int[] localVariable1 = ??// I want to move the value returned from the method into localVariable1.  

目前我的错误是:

'System.Threading.Thread.Thread(System.Threading.ParameterizedThreadStart)'的最佳重载方法匹配有一些无效的参数

&安培;

参数1:无法从'方法组'转换为'System.Threading.ParameterizedThreadStart'

目前这样做没有线程,如:

   int[] localVariabl1 = Class2.ArrayWorkings(1, MyGlobals.variable1);

4 个答案:

答案 0 :(得分:9)

您可以使用lambda:

修复构造函数
Thread t = new Thread(() => Class2.ArrayWorkings(1, MyGlobals.variable1));

但是这不会让你(正如Jon所说)直接得到结果 - 否则你再次编写同步代码。你可以改为寻找某种回调;大概你需要回到UI线程,所以:

Thread t = new Thread(() => {
    // this runs on the worker
    int[] localVariabl1 = Class2.ArrayWorkings(1, MyGlobals.variable1);
    this.Invoke((MethodInvoker)delegate {
        // now we're back on the UI thread!
        update the UI from localVariabl1
    });
});
t.Start()

我可能会建议使用线程池,但是:

ThreadPool.QueueUserWorkItem(delegate {
    // this runs on the worker
    int[] localVariabl1 = Class2.ArrayWorkings(1, MyGlobals.variable1);
    this.Invoke((MethodInvoker)delegate {
        // now we're back on the UI thread!
        update the UI from localVariabl1
    });
});

答案 1 :(得分:2)

这样做的一种方法如下:

ThreadStart starter = delegate { Class2.ArrayWorkings(1, MyGlobals.variable1); };
var thread = new Thread(starter);
thread.Start();

编辑:刚看到你也想从线程中捕获返回值。 您可能必须使用Marc的答案中提到的ThreadPool.QueueUserWorkItem

您可能想要查看的内容是.NET Framework 4.5(仍在候选发布版中) 使用异步编程使生活更轻松。

await operator in .NET 4.5

答案 2 :(得分:2)

你需要一个 ThreadStart 代表。如果你真的不希望UI受到影响,你应该使用 BackgroundWorker 类。

答案 3 :(得分:1)

Tasks为执行最终返回值的异步作业提供了一个简单的界面。例如Task<string>是一个任务(最终)返回一个字符串,其中Task<int[]>将返回一个整数数组。

int[] localVariable1;

// start the task
Task<int[]> myTask = Task.Factory.StartNew<int[]>(() => Class2.ArrayWorkings(1, MyGlobals.Variable1);

// when it is finished get the result and place in local variable
myTask.OnCompleted(task => localVariable1 = task.Result;);

如果要在异步操作完成后更新UI组件,则必须使用Invoke(对于winforms)。这允许您使用UI线程上的对象(例如按钮和标签)。

myTask.OnCompleted(task => localVariable1.Invoke(new Action(() =>
    localVariable1.Value = task.Result; )));