2

在我的程序中有一个连续调用的方法,所以我想对它进行线程化,以使 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

4 回答 4

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
    });
});
于 2012-06-27T06:30:13.893 回答
2

您必须放置一个ThreadStart委托。如果你真的不希望 UI 受到影响,你应该使用BackgroundWorker类。

于 2012-06-27T06:30:44.817 回答
2

一种方法如下:

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

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

您可能想看看 .NET Framework 4.5(仍处于候选版本中)使异步编程的生活更轻松。

.NET 4.5 中的等待运算符

于 2012-06-27T06:30:06.043 回答
1

任务为执行最终将返回值的异步作业提供了一个简单的接口。Task<string>例如,一个任务(最终)返回一个字符串,其中 a将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; )));
于 2012-06-27T06:36:10.503 回答