- android - 多次调用 OnPrimaryClipChangedListener
- android - 无法更新 RecyclerView 中的 TextView 字段
- android.database.CursorIndexOutOfBoundsException : Index 0 requested, 光标大小为 0
- android - 使用 AppCompat 时,我们是否需要明确指定其 UI 组件(Spinner、EditText)颜色
我是 SO 的新作者,请多多包涵。
我有一个带有双工服务契约(Contract)的 WCF 服务。该服务契约(Contract)有一个操作联系人,假设要进行长时间的数据处理。我不得不将并发数据处理的数量限制为最多 3 个。我的问题是,在数据处理之后,我需要返回到相同的服务实例上下文,因此我回调传递数据处理结果的发起端点。我需要指出,由于各种原因,我只能使用 TPL 数据流和 WCF 双工。
这是我到目前为止所写内容的演示
在控制台库中我模拟 WCF 调用
class Program
{
static void Main(string[] args)
{
// simulate service calls
Enumerable.Range(0, 5).ToList().ForEach(x =>
{
new System.Threading.Thread(new ThreadStart(async () =>
{
var service = new Service();
await service.Inc(x);
})).Start();
});
}
}
这应该是 WCF 服务
// service contract
public class Service
{
static TransformBlock<Message<int>, Message<int>> transformBlock;
static Service()
{
transformBlock = new TransformBlock<Message<int>, Message<int>>(x => Inc(x), new ExecutionDataflowBlockOptions
{
MaxDegreeOfParallelism = 3
});
}
static Message<int> Inc(Message<int> input)
{
System.Threading.Thread.Sleep(100);
return new Message<int> { Token = input.Token, Data = input.Data + 1 };
}
// operation contract
public async Task Inc(int id)
{
var token = Guid.NewGuid().ToString();
transformBlock.Post(new Message<int> { Token = token, Data = id });
while (await transformBlock.OutputAvailableAsync())
{
Message<int> message;
if (transformBlock.TryReceive(m => m.Token == token, out message))
{
// do further processing using initiator service instance members
// something like Callback.IncResult(m.Data);
break;
}
}
}
}
public class Message<T>
{
public string Token { get; set; }
public T Data { get; set; }
}
操作契约(Contract)并不是异步所必需的,但我需要 OutputAvailableAsync 通知。
这是一个好的方法还是有更好的解决方案适合我的场景?
提前致谢。
最佳答案
首先,我认为您不应该像现在这样使用 token 。在进程之间进行通信时,唯一标识符很有用。但是,当您在单个进程中时,只需使用引用相等即可。
要真正回答您的问题,我认为(某种)繁忙的循环不是一个好主意。
一个更简单的异步节流解决方案是使用 SemaphoreSlim
.像这样的东西:
static readonly SemaphoreSlim Semaphore = new SemaphoreSlim(3);
// operation contract
public async Task Inc(int id)
{
await Semaphore.WaitAsync();
try
{
Thread.Sleep(100);
var result = id + 1;
// do further processing using initiator service instance members
// something like Callback.IncResult(result);
}
finally
{
Semaphore.Release();
}
}
如果你真的想(或必须?)使用数据流,你可以使用 TaskCompletionSource
用于操作和 block 之间的同步。操作方法将等待 TaskCompletionSource
的 Task
并且 block 将在完成对该消息的计算时设置它:
private static readonly ActionBlock<Message<int>> Block =
new ActionBlock<Message<int>>(
x => Inc(x),
new ExecutionDataflowBlockOptions
{
MaxDegreeOfParallelism = 3
});
static void Inc(Message<int> input)
{
Thread.Sleep(100);
input.TCS.SetResult(input.Data + 1);
}
// operation contract
public async Task Inc(int id)
{
var tcs = new TaskCompletionSource<int>();
Block.Post(new Message<int> { TCS = tcs, Data = id });
int result = await tcs.Task;
// do further processing using initiator service instance members
// something like Callback.IncResult(result);
}
关于c# - WCF 双工中的 TPL 数据流 block ,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/15547607/
我有以下 TPL 数据流,当使用谓词过滤从 TransformBlock 传递到 ActionBlock 的项目时,它永远不会完成。 如果谓词对任何项目返回 false,则数据流挂起。 请有人提供一些
我是 smarty 的新手,所以我不确定这是否会导致我遗漏某些内容,但目前我正在尝试从 css 文件中提取一个类。 到目前为止,我已经设置了 2 个类 mainbackground 和 body,ma
如何强制 TPL 使用固定数量的线程?我知道 MaxDegreeOfParallelism 可用于设置上限,但我希望上限等于下限。这可能吗?怎么办? 因为我知道有人会问 =) 是的,我确定我想这样做,
我正在尝试使用 GXT 3.0 的 XTemplates(类似于 EXT),这里有 2 个具有以下关系的简单 java 对象: class A { String name; public
我刚刚将 Visual Studio 11 Beta 升级到新的 Visual Studio 2012 RC,并且在引用 TPL 数据流时遇到了问题。 首先,我尝试像以前一样通过从框架中添加引用来引用
我需要制作可扩展的流程。该进程主要有 I/O 操作和一些次要的 CPU 操作(主要是反序列化字符串)。该过程在数据库中查询 url 列表,然后从这些 url 中获取数据,将下载的数据反序列化为对象,然
我们有一个 TPL 数据流管道,其中包含以下 block : 变换 block A:Http post call 转换 block B:数据库 IO Transform Block C:一些单位转换数
我有一个 BufferBlock 来发布消息: public class DelimitedFileBlock : ISourceBlock { private ISourceBlock _s
我想在 Windows Azure 上的工作进程中使用 TPL。我希望在队列中添加一个 IJob,它有一个 Run 方法,因此工作线程将包括: 循环 将项目从队列中取出 使用TPL调用IJob.Run
我尝试创 build 计良好的 TPL 数据流管道,以优化系统资源的使用。我的项目是一个 HTML 解析器,它将解析后的值添加到 SQL Server DB 中。我已经有了 future 管道的所有方
我想为特定的内容类型覆盖 page.tpl.php。 我已经尝试过这些东西,对我没有任何作用。 page--article.tpl.php page--node--article.tpl.php pa
我已经完成了这个 POC 并验证了当你创建 4 个线程并在四核机器上运行它们时,所有的核心都会变得忙碌——所以,CLR 已经在不同的核心上有效地调度了线程,那么为什么要使用 TASK 类呢? 我同意
使用Visual Studio Concurrency Visualizer我现在明白为什么切换到 Parallel.For 没有任何好处:只有 9% 的时间机器忙于执行代码,其余的时间为 71% 的
我的代码中有以下使用 TPL 的设置: 我的类中的一个字段:private CancellationTokenSource _cancellationTokenSource; 每次我创建使用特定取消
我有一个 Windows 服务,它在经过漫长的过程后发送电子邮件。每当有表条目并处理它并将其发送出去时,该服务就会继续从数据库表中获取电子邮件数据。 目前它是一个多线程应用程序,我们在生产服务器中将线
刚刚使用 TPL DataFlow 编写了示例生产者消费者模式。我在这里有一些基本问题。 只有在生产者发布所有项目后,消费者才处于事件状态。异步是指生产任务和消费任务都可以并行运行。 给消费者一个 s
我正在使用 TPL,需要有一个长时间运行的 TPL 任务将结果发送到父 UI 线程而不终止。我已经尝试了几种方法,并且已经在谷歌上搜索了很多。有谁知道如何通过 TPL 实现这一点? 最佳答案 您可以传
我有一个以这种方式设置的 TPL 数据流: 下载字节数组 处理数据 将处理后的数据流式传输到另一个位置 此流程运行良好,但偶尔会在下载文件时遇到备份、连接问题等。我想做的是并行下载,但仍确保执行第 3
我有一个应该批量调用并压缩大文件的控制台应用程序,我想使用 DataFlow,除了完成之外一切正常 请考虑以下代码 public static void CompressFiles(string fo
当你生成多个任务时,像这样: for (int i = 0; i ((stateObject) => { tls.Value = (int)stateObject;
我是一名优秀的程序员,十分优秀!