Warning: file_get_contents(/data/phpspider/zhask/data//catemap/7/sql-server/22.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 无法中止还原数据库_C#_Sql Server_Database_Smo - Fatal编程技术网

C# 无法中止还原数据库

C# 无法中止还原数据库,c#,sql-server,database,smo,C#,Sql Server,Database,Smo,我想向用户提供“取消”按钮,以中止正在进行的还原。为此,在Restore.PercentComplete事件处理程序中,我检查用户是否单击了取消按钮并调用Restore.Abort()。但这无助于: SMO引发异常: 服务器“MICHAEL7”的还原失败。 执行Transact-SQL语句或批处理时发生异常。 堆栈跟踪:位于Microsoft.SqlServer.Management.Smo.Restore.SqlRestore(服务器srv) 数据库永远处于“恢复”模式。以下是相关代码: us

我想向用户提供“取消”按钮,以中止正在进行的还原。为此,在
Restore.PercentComplete
事件处理程序中,我检查用户是否单击了取消按钮并调用
Restore.Abort()
。但这无助于:

SMO引发异常:

服务器“MICHAEL7”的还原失败。
执行Transact-SQL语句或批处理时发生异常。
堆栈跟踪:位于Microsoft.SqlServer.Management.Smo.Restore.SqlRestore(服务器srv)

数据库永远处于“恢复”模式。以下是相关代码:

using Microsoft.SqlServer.Management.Common;
using Microsoft.SqlServer.Management.Smo;

private volatile bool _CancelRestore = false;
private Restore _RestoreDB;
private Server _myServer;
private Database _currentDatabase;

// user hits Cancel buttton
public void CancelRestore()
{
    _CancelRestore = true;
}

// Restore.PercentComplete event handler
private static void CompletionStatusInPercent(object sender, PercentCompleteEventArgs args) 
{
    if (_CancelRestore)
    {
        _RestoreDB.Abort();

          // Disable the kills to let some time to Abort()

        // Stop all processes running on the _currentDatabase database
        // _myServer.KillAllProcesses(_currentDatabase.Name);

        // Stop the _currentDatabase database
        // NOTE: it is a temp name DB: I do not restore over my application DB!
        // _myServer.KillDatabase(_currentDatabase.Name);
    }
    else
    {
        Console.Clear();
        Console.WriteLine("Percent completed: {0}%.", args.Percent);
    }
}
备份/恢复功能是在本文的帮助下实现的:


谢谢。

我知道这是一个老问题,但我也遇到了同样的问题,我找到了一个适合我的解决方案

我不使用KillDatabase,而是使用以下内容:

sqlRestore.Abort();
sqlRestore.Wait(); //This will wait until the restore operation is canceled
Database db = _server.Database(databaseName);
if (db != null)
    db.Drop(); // This will drop the "half" restored Database
应该说,我正在使用SqlRestoreAsync

KillDatabase()将终止所有连接,因此KillAllProcesses()在这里已过时

她是我的全部代码:

public async Task<bool> Restore(string backupFile, string databaseName, IProgress<int> progress, CancellationToken ct)
{
    Restore sqlRestore = null;

    bool result = await Task.Run(() =>
    {
        try
        {
            var deviceItem = new BackupDeviceItem(backupFile, DeviceType.File);
            sqlRestore = new Restore
            {
                Action = RestoreActionType.Database,
                Database = databaseName,
                Partial = false,
                ReplaceDatabase = true,
                PercentCompleteNotification = 1
            };
            sqlRestore.PercentComplete += (s, e) => progress.Report(e.Percent);
            sqlRestore.Devices.Add(deviceItem);

            if (_server.Databases[databaseName] != null)
                _server.KillAllProcesses(databaseName);

            sqlRestore.SqlRestoreAsync(_server);

            while (sqlRestore.AsyncStatus.ExecutionStatus == ExecutionStatus.InProgress)
            {
                ct.ThrowIfCancellationRequested();
                Thread.Sleep(500);
            }

            if (sqlRestore.AsyncStatus.ExecutionStatus == ExecutionStatus.Succeeded)
            {
                Database db = _server.Databases[databaseName];
                if (db != null)
                    db.SetOnline();

                _server.Refresh();
                return true;
            }
            return false;
        }
        catch (OperationCanceledException)
        {
            sqlRestore.Abort();
            sqlRestore.Wait();
            Database db = _server.Databases[databaseName];
            if (db != null)
                db.Drop();
            return true;
        }
        catch (ConnectionFailureException)
        {
            return false;
        }
        catch (Exception ex)
        {
            _server.KillDatabase(databaseName);
            return false;
        }
    }, ct);
    return result;
}
公共异步任务还原(字符串备份文件、字符串数据库名、IProgress进度、CancellationToken ct)
{
Restore-sqlRestore=null;
bool result=等待任务。运行(()=>
{
尝试
{
var deviceItem=new BackupDeviceItem(backupFile,DeviceType.File);
sqlRestore=newrestore
{
Action=RestoreActionType.Database,
Database=databaseName,
部分=错误,
ReplaceDatabase=true,
完成百分比化=1
};
sqlRestore.PercentComplete+=(s,e)=>progress.Report(e.Percent);
sqlRestore.Devices.Add(deviceItem);
if(_server.Databases[databaseName]!=null)
_server.killallprocesss(databaseName);
sqlRestore.SqlRestoreAsync(_server);
while(sqlRestore.AsyncStatus.ExecutionStatus==ExecutionStatus.InProgress)
{
ct.ThrowIfCancellationRequested();
睡眠(500);
}
if(sqlRestore.AsyncStatus.ExecutionStatus==ExecutionStatus.successed)
{
Database db=_server.Databases[databaseName];
如果(db!=null)
db.SetOnline();
_server.Refresh();
返回true;
}
返回false;
}
捕获(操作取消异常)
{
sqlRestore.Abort();
sqlRestore.Wait();
Database db=_server.Databases[databaseName];
如果(db!=null)
db.Drop();
返回true;
}
捕获(连接失败异常)
{
返回false;
}
捕获(例外情况除外)
{
_server.KillDatabase(databaseName);
返回false;
}
},ct);
返回结果;
}

我知道这是一个老问题,但我也遇到了同样的问题,我找到了一个适合我的解决方案

我不使用KillDatabase,而是使用以下内容:

sqlRestore.Abort();
sqlRestore.Wait(); //This will wait until the restore operation is canceled
Database db = _server.Database(databaseName);
if (db != null)
    db.Drop(); // This will drop the "half" restored Database
应该说,我正在使用SqlRestoreAsync

KillDatabase()将终止所有连接,因此KillAllProcesses()在这里已过时

她是我的全部代码:

public async Task<bool> Restore(string backupFile, string databaseName, IProgress<int> progress, CancellationToken ct)
{
    Restore sqlRestore = null;

    bool result = await Task.Run(() =>
    {
        try
        {
            var deviceItem = new BackupDeviceItem(backupFile, DeviceType.File);
            sqlRestore = new Restore
            {
                Action = RestoreActionType.Database,
                Database = databaseName,
                Partial = false,
                ReplaceDatabase = true,
                PercentCompleteNotification = 1
            };
            sqlRestore.PercentComplete += (s, e) => progress.Report(e.Percent);
            sqlRestore.Devices.Add(deviceItem);

            if (_server.Databases[databaseName] != null)
                _server.KillAllProcesses(databaseName);

            sqlRestore.SqlRestoreAsync(_server);

            while (sqlRestore.AsyncStatus.ExecutionStatus == ExecutionStatus.InProgress)
            {
                ct.ThrowIfCancellationRequested();
                Thread.Sleep(500);
            }

            if (sqlRestore.AsyncStatus.ExecutionStatus == ExecutionStatus.Succeeded)
            {
                Database db = _server.Databases[databaseName];
                if (db != null)
                    db.SetOnline();

                _server.Refresh();
                return true;
            }
            return false;
        }
        catch (OperationCanceledException)
        {
            sqlRestore.Abort();
            sqlRestore.Wait();
            Database db = _server.Databases[databaseName];
            if (db != null)
                db.Drop();
            return true;
        }
        catch (ConnectionFailureException)
        {
            return false;
        }
        catch (Exception ex)
        {
            _server.KillDatabase(databaseName);
            return false;
        }
    }, ct);
    return result;
}
公共异步任务还原(字符串备份文件、字符串数据库名、IProgress进度、CancellationToken ct)
{
Restore-sqlRestore=null;
bool result=等待任务。运行(()=>
{
尝试
{
var deviceItem=new BackupDeviceItem(backupFile,DeviceType.File);
sqlRestore=newrestore
{
Action=RestoreActionType.Database,
Database=databaseName,
部分=错误,
ReplaceDatabase=true,
完成百分比化=1
};
sqlRestore.PercentComplete+=(s,e)=>progress.Report(e.Percent);
sqlRestore.Devices.Add(deviceItem);
if(_server.Databases[databaseName]!=null)
_server.killallprocesss(databaseName);
sqlRestore.SqlRestoreAsync(_server);
while(sqlRestore.AsyncStatus.ExecutionStatus==ExecutionStatus.InProgress)
{
ct.ThrowIfCancellationRequested();
睡眠(500);
}
if(sqlRestore.AsyncStatus.ExecutionStatus==ExecutionStatus.successed)
{
Database db=_server.Databases[databaseName];
如果(db!=null)
db.SetOnline();
_server.Refresh();
返回true;
}
返回false;
}
捕获(操作取消异常)
{
sqlRestore.Abort();
sqlRestore.Wait();
Database db=_server.Databases[databaseName];
如果(db!=null)
db.Drop();
返回true;
}
捕获(连接失败异常)
{
返回false;
}
捕获(例外情况除外)
{
_server.KillDatabase(databaseName);
返回false;
}
},ct);
返回结果;
}

设置一个断点,查看
CompletionStatusInPercent
是否经常被点击(应该是这样),同时在
\u CancelRestore
中添加一个
volatile
关键字,这将禁用bool的任何CPU缓存,并强制线程检查bool的实际值(尽管这并不能保证)。hi@oleksii。谢谢你的邀请。断点就在那里,可以正常访问。我想问题出在SMO的某个地方。我需要一个备份/恢复中止的工作示例。注释掉Kill!你没有给它时间让它重新振作起来!嗨,托尼,干掉所有的事。仍然是相同的异常。如果像在“取消还原”中那样手动执行,会发生什么情况?不能说是我自己做的,所以