gpt4 book ai didi

c# - 用于处理 MySQL 的带有队列的线程

转载 作者:行者123 更新时间:2023-11-29 06:50:29 25 4
gpt4 key购买 nike

现在我在一个类中有很多 INSERT/UPDATE/DELETE/SELECT 方法。它们都共享一个 Connection、一个 DataReader 和一个 Command。但是从数据库下载数据或上传数据时,它们会卡住用户界面。在本地网络上没问题,但由于它使用外部服务器作为数据库,有时会卡住。所以我想在另一个线程上创建所有 MySQL 类。

我需要像 DoThisInAnotherThread(mysql.UpdateTable) 这样的东西。但必须有某种队列,因为所有方法都使用相同的连接和相同的 DataReader。并且让每一种方法来建立自己的连接看起来都不像是最好的解决方案。

我正在寻找最好和最简单的解决方案。类似 queue for Tasks 的东西,它会被另一个线程检查并执行,但它不会为空。

我试过BackgroundWorker,但是没有队列。我听说过有关启动自己的线程的消息,但我看不到如何让它运行并等待任务的方法。

谢谢。

最佳答案

您可以使用工作队列,它将在单个线程上执行所有工作。在那里您可以保持单个 sql 连接,并且同步将很简单,因为所有命令都是按顺序执行的。

查看下面的示例 WorkQueue 实现(注意它缺少异常处理):

using System;
using System.Threading;
using System.Threading.Tasks;
using System.Collections.Concurrent;

class App
{
static void Main()
{
var q = new WorkQueue();
q.Execute(() => Console.WriteLine("A"));
q.Execute(() => Console.WriteLine("B"));
Task<int> t = q.Execute(() => 33);

Console.WriteLine(t.Result);
q.Dispose();
}

}

public class WorkQueue : IDisposable
{
private readonly Thread thread;
private readonly BlockingCollection<Action> queue;
public WorkQueue()
{
this.queue = new BlockingCollection<Action>();
this.thread = new Thread(DoWork);
this.thread.Start();
}

public Task<T> Execute<T>(Func<T> f)
{
if (this.queue.IsCompleted) return null;
var source = new TaskCompletionSource<T>();
Execute(() => source.SetResult(f()));
return source.Task;
}

public void Execute(Action f)
{
if (this.queue.IsCompleted) return;
this.queue.Add(f);
}

public void Dispose()
{
this.queue.CompleteAdding();
this.thread.Join();
}

private void DoWork()
{
foreach (var action in this.queue.GetConsumingEnumerable())
{
action();
}
}
}

关于c# - 用于处理 MySQL 的带有队列的线程,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/15746765/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com