我正在尝试使用新的async/await功能来异步处理数据库.由于一些请求可能很长,我希望能够取消它们.我遇到的问题是TransactionScope显然有一个线程亲和力,似乎在取消任务时,它Dispose()会在一个错误的线程上运行.
具体来说,打电话时.TestTx()我得到以下AggregateException含InvalidOperationException上task.Wait ():
"A TransactionScope must be disposed on the same thread that it was created."
Run Code Online (Sandbox Code Playgroud)
这是代码:
public void TestTx () {
var cancellation = new CancellationTokenSource ();
var task = TestTxAsync ( cancellation.Token );
cancellation.Cancel ();
task.Wait ();
}
private async Task TestTxAsync ( CancellationToken cancellationToken ) {
using ( var scope = new TransactionScope () ) {
using ( var connection = new SqlConnection ( m_ConnectionString …Run Code Online (Sandbox Code Playgroud) 我在向SQL Server上的FILESTREAM列写入大量数据时遇到问题.具体而言,围绕1.5-2GB小巧的文件的处理很好,但是当规模达到6GB和起来,我得到间歇性 IOException "句柄是无效的"关于.CopyTo()对传输结束.
我想过在块写入数据,但允许将数据追加到它,这破坏了完全的大文件的性能之前的SQL Server副本领域的备份文件.
这是代码:
public long AddFragment (string location , string description = null)
{
const string sql =
@"insert into [Fragment] ([Description],[Data]) " +
"values (@description,0x); " +
"select [Id], [Data].PathName(), " +
"GET_FILESTREAM_TRANSACTION_CONTEXT() " +
"from " +
"[Fragment] " +
"where " +
"[Id] = SCOPE_IDENTITY();";
long id;
using (var scope = new TransactionScope(
TransactionScopeOption.Required,
new TransactionOptions {
Timeout = TimeSpan.FromDays(1)
}))
{
using (var connection = new SqlConnection(m_ConnectionString)) …Run Code Online (Sandbox Code Playgroud) 我正在使用TPL Dataflow处理图像.我收到处理请求,从流中读取图像,应用几个转换,然后将生成的图像写入另一个流:
Request -> Stream -> Image -> Image ... -> Stream
Run Code Online (Sandbox Code Playgroud)
为此,我使用块:
BufferBlock<Request>
TransformBlock<Request,Stream>
TransformBlock<Stream,Image>
TransformBlock<Image,Image>
TransformBlock<Image,Image>
...
writerBlock = new ActionBlock<Image>
Run Code Online (Sandbox Code Playgroud)
问题是初始Request是包含创建结果所需的一些数据Stream以及我需要的一些额外信息.我是否必须将原始Request(或其他一些上下文对象)传递给writerBlock所有其他块,如下所示:
TransformBlock<Request,Tuple<Request,Stream>>
TransformBlock<Tuple<Request,Stream>,Tuple<Request,Image>>
TransformBlock<Tuple<Request,Image>,Tuple<Request,Image>>
...
Run Code Online (Sandbox Code Playgroud)
(这很难看),还是有办法将第一个块链接到最后一个块(或者,推广到需要附加数据的块)?
假设我有一个类,我希望有时*(但现在总是)拦截一些(但不是全部)方法.我理解它的方式,可以InterceptAround()在我的Ninject模块(在更高级别的代码中)或者在这些方法上(在实现级别)使用InterceptAttribute派生的属性来完成.
我真的不喜欢第一种方式,因为它需要消费者知道细节,有很多类有很多方法.但我也不喜欢第二种方式,因为我没有看到如何禁用(或者更确切地说,不启用)拦截,因为属性与代码融合.
有没有一些已知的方法来解决这个问题?
*:适用于应用程序的生命周期.
我有class SetIdentitySeedOperation: MigrationOperation,它设置指定表的标识值。为了将其连接起来,我使用了一个自定义的SqlServerMigrationSqlGenerator,因此如果我手动写入.AddOperation(new SetIdentitySeedOperation(...))迁移的void Up(),我的Generate方法就会被调用,并且我会在那里生成适当的 SQL。
向迁移脚手架注册此自定义操作的机制是什么,以便生成添加此操作的代码Add-Migration?
更新:我一直在查看 EF 迁移源代码,似乎要搭建的迁移操作列表来自对 的调用EdmModelDiffer.Diff(),并且EdmModelDiffer是内部的,因此似乎无法将您自己的约定或属性插入到脚手架引擎。
鉴于此,迁移操作和 SQL 生成的公共表面的存在似乎毫无意义,因为它没有为库用户提供真正的扩展点,需要用户手动编写对其自定义迁移操作的显式调用,这就是在必须编写一些样板代码将 SQL 生成包装到操作中之后。
那么整个机制是否仅在相同的代码针对不同的数据库时才有用?
.net c# entity-framework entity-framework-6 entity-framework-migrations
.net ×5
c# ×5
aop ×1
async-await ×1
database ×1
entity-framework-migrations ×1
ninject ×1
sql-server ×1
stream ×1
tpl-dataflow ×1
transactions ×1