c# - 异步线程

标签 c# wpf multithreading

我想知道在哪里可以获得多线程或异步线程的示例。

在我忙碌的应用程序中,我必须在应用程序后台运行一个线程来获取正在更改的值。每当这个值达到一定数量时,就需要调用另一个函数。所有这些都必须在程序后台运行,以便用户仍然可以在应用程序上执行其他操作。

任何可以提供帮助的示例或链接将不胜感激。

最佳答案

为了总结这些选项,我将尝试在此处列出它们(也许将其设为社区 wiki 是个好主意)。

首先,你可以简单地在另一个 thread 中启动一个函数:

Thread t = new Thread( ThreadProc );
t.Start();
// now you can wait for thread to finish with t.Join() or just continue
// Thread.IsBackground allows to control how thread lifetime influences
// the lifetime of the application

...
static void ThreadProc() {...} // can also be non-static, but for simplicity....

然后你可以使用BackgroundWorker :

BackgroundWorker bgWorker = new BackgroundWorker();
bgWorker.DoWork += MyFunction;
bgWorker.RunWorkerAsync();

voud MyFunction(object o, DoWorkEventArgs args) {...}

您可以使用 ProgressChangedRunWorkerCompleted 事件进行更多控制(以及 WorkerReportsProgress 和其他属性)

另一个选择是使用 ThreadPool ,如果您的方法不会花费太多时间:

ThreadPool.QueueUserWorkItem(new WaitCallback(ThreadProc));
...
static void ThreadProc(Object stateInfo) { ... }

另一种选择是调用 BeginInvoke on a delegate :

public delegate int MyDelegate(...);

MyDelegate del = SomeFunction;                     
IAsyncResult ar = del.BeginInvoke(...);
int result = del.EndInvoke(ar);

这将在线程池中的线程上执行。如果需要等待调用线程,可以使用IAsyncResult.IsCompleted,但它会阻塞调用线程。

当然,您可以使用 Task :

var task = Task.Factory.StartNew(() => MyMethod());

这还将在线程池中的线程上执行 MyMethod,因此会出现相同的警告(尽管您可以使用 TaskCreationOptions.LongRunning 来确保新线程是总是创建)。在某些情况下(当您等待任务时)它甚至可以在同一线程上执行,但它经过了很好的优化,因此您不必担心这一点。

这可能是简单性与控制性之间最佳权衡的选择(当然,没有真正的“最佳”)。以下是好处(无耻地从 Jon Skeet's answer 窃取):

  • 添加延续 (Task.ContinueWith)
  • 等待多个任务完成(全部或任意)
  • 捕获任务中的错误并稍后进行询问
  • 捕获取消(并允许您指定取消开始)
  • 可能有返回值
  • 在 C# 5 中使用等待
  • 更好地控制调度(如果要长时间运行,请在创建任务时说明,以便任务调度程序可以考虑到这一点)

关于c# - 异步线程,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/16332190/

相关文章:

c# - 如何继承NuGet包中引用的程序集

wpf - 滚动/适合带有复选框的图像

wpf - 为什么 WPF 不能绑定(bind)到 UserControl 属性?

WPF 应用程序行为取决于 Windows 用户访问级别

c++ - 对各种缓冲区的线程访问

c# - 将.cs转换为.dll CS0246错误

c# - Entity Framework Core 3.1 从存储过程返回值 (int)

multithreading - 为什么此Scala代码在一个线程中执行两个Future?

c# - C# 中的 NamedPipe 超时

带线程的代码比没有线程花费的时间更长