C# 如何在C中使用ThreadPool调用带参数的函数#
根据另一篇文章中的建议,我已经能够为一个使用多线程和 有一个开始按钮和一个停止按钮。“开始”按钮调用一个需要几分钟才能完成的函数。只要我想,停止按钮就会停止函数的执行 这段代码与没有参数的SlowFunction()完美结合,但我的实际函数需要一个字符串 参数起作用,定义如下:C# 如何在C中使用ThreadPool调用带参数的函数#,c#,function,threadpool,C#,Function,Threadpool,根据另一篇文章中的建议,我已经能够为一个使用多线程和 有一个开始按钮和一个停止按钮。“开始”按钮调用一个需要几分钟才能完成的函数。只要我想,停止按钮就会停止函数的执行 这段代码与没有参数的SlowFunction()完美结合,但我的实际函数需要一个字符串 参数起作用,定义如下: public void SlowFunction(string str) {...} 然后,我的问题是无法使用“WaitCallback(…)”部分中的参数调用函数 在这段代码中,因为SlowFunction()没有参
public void SlowFunction(string str) {...}
然后,我的问题是无法使用“WaitCallback(…)”部分中的参数调用函数
在这段代码中,因为SlowFunction()没有参数,所以没有问题,我可以这样调用函数
ThreadPool.QueueUserWorkItem(new WaitCallback(SlowFunction), cts.Token);
但是如果不使用不需要参数的SlowFunction(),而是使用需要强制字符串参数的新SlowFunction1(Somestring):
public void SlowFunction1(string sec)
{
double sec1 = Convert.ToDouble(sec);
var end = DateTime.Now + TimeSpan.FromSeconds(sec1);
while (DateTime.Now < end)
{ }
MessageBox.Show("Process finished1");
}
如何使用WaitCallback()调用带参数的SlowFunction1?
如何修改SlowFunction 1的定义?我已经尝试了下面的方法,但不起作用
public void SlowFunction(string str, object obj)
{
CancellationToken token = (CancellationToken)obj;
..
}
下面是我目前正在使用的不需要参数的SlowFunction代码。谢谢你的帮助
namespace SampleStartStop
{
public partial class Form1 : Form
{
// Create the token source.
CancellationTokenSource cts = new CancellationTokenSource();
public Form1()
{
InitializeComponent();
}
private void btnStart_Click(object sender, EventArgs e)
{
if (cts != null)
{
cts.Cancel();
}
cts = new CancellationTokenSource();
ThreadPool.QueueUserWorkItem(new WaitCallback(SlowFunction), cts.Token);
}
private void btnStop_Click(object sender, EventArgs e)
{
if (cts != null)
{
cts.Cancel();
cts = null;
MessageBox.Show("Processing cancelled");
}
}
public void SlowFunction(object obj)
{
CancellationToken token = (CancellationToken)obj;
var end = DateTime.Now + TimeSpan.FromSeconds(4);
while (DateTime.Now < end)
{
if (token.IsCancellationRequested)
{
break;
}
}
if (!token.IsCancellationRequested)
{
MessageBox.Show("Processing finished");
}
}
}
}
名称空间SampleStartStop
{
公共部分类Form1:Form
{
//创建令牌源。
CancellationTokenSource cts=新的CancellationTokenSource();
公共表格1()
{
初始化组件();
}
私有void btnStart_单击(对象发送方,事件参数e)
{
如果(cts!=null)
{
cts.Cancel();
}
cts=新的CancellationTokenSource();
ThreadPool.QueueUserWorkItem(新的WaitCallback(SlowFunction),cts.Token);
}
私有void btnStop_单击(对象发送方,事件参数e)
{
如果(cts!=null)
{
cts.Cancel();
cts=null;
MessageBox.Show(“处理已取消”);
}
}
公共无效慢函数(对象obj)
{
CancellationToken=(CancellationToken)obj;
var end=DateTime.Now+TimeSpan.FromSeconds(4);
while(DateTime.Now
有很多方法可以做到这一点,下面是一些方法:
1使用state
参数传递单个变量
void Method1( object state )
{
var sec = (string)state;
// use sec here
}
// call this using
ThreadPool.QueueUserWorkItem( Method1, "20" );
2使用state
参数传递包含多个变量的对象
class Foo
{
public string Seconds { get; set; }
public int OtherStuff { get; set; }
}
void Method2( object state )
{
var args = (Foo)state;
// use args.Seconds and args.OtherStuff here
}
// call this like so:
var args = new Foo()
{
Seconds = "20",
OtherStuff = 4711
};
ThreadPool.QueueUserWorkItem( Method2, args );
3创建一个包含变量和代码的worker类
class Worker
{
public string Seconds { get; set; }
public int OtherStuff { get; set; }
public void DoWork( object unused )
{
// use this.Seconds and this.OtherStuff here
}
}
// call like so:
var worker = new Worker()
{
Seconds = "20",
OtherStuff = 4711
};
ThreadPool.QueueUserWorkItem( worker.DoWork );
4使用匿名委托
string sec = "20";
ThreadPool.QueueUserWorkItem( delegate
{
// use sec here
} );
很明显,您正在使用.Net4.0或更高版本。没有理由直接使用
ThreadPool.Queue…
。使用时,它提供了许多有用的功能
解决这个问题的简单方法是使用lambda表达式
private void btnStart_Click(object sender, EventArgs e)
{
if (cts != null)
{
cts.Cancel();
}
cts = new CancellationTokenSource();
Task.Factory.StartNew(()=> SlowFunction(SomeString, cts.Token), cts.Token, TaskCreationOptions.None, TaskScheduler.Default);
}
public void SlowFunction(string str, CancellationToken token)
{
//Your code
}
请注意,您不再需要将CancellationToken
作为对象键入。它可以是强类型的
也要知道。如果您在.Net4.5中,请使用Task.Run
,否则请明确指定TaskScheduler
。我们真的需要这些粗体标题吗?它只是增加了噪音。不,我想它们确实有点太大胆了,呵呵。你好,克里斯,谢谢你分享这4种方法,我仍然不太清楚如何使用它们。我是否应该在您放置的注释行中插入对函数的调用?而不是使用字符串,而是使用这个.seconds?请您给我举一个更详细的例子,说明如何与代表pleaseHi Sriram相处,谢谢您的帮助。我能够实现您的解决方案,它与StarNew和Task.Run一起工作。非常感谢。
private void btnStart_Click(object sender, EventArgs e)
{
if (cts != null)
{
cts.Cancel();
}
cts = new CancellationTokenSource();
Task.Factory.StartNew(()=> SlowFunction(SomeString, cts.Token), cts.Token, TaskCreationOptions.None, TaskScheduler.Default);
}
public void SlowFunction(string str, CancellationToken token)
{
//Your code
}